среда, 4 марта 2020 г.

PiPnpRtlCtx

since w8 Microsoft introduced for PnP devices management new structure with lots of function pointers - PiPnpRtlCtx

It`s called from lots of exported functions, but I think most comfortable for RE are IoOpenDeviceRegistryKeyIoOpenDeviceInterfaceRegistryKey. You can gather address of PiPnpRtlCtx with one pass of disassembling - it will be first loaded address in .data section after call to ExAcquireResourceExclusiveLite

This structure allocating and partially initializing in function PnpCtxOpenMachine. There are at least 3 version with different size:
  • 0xac for 32 bit/0x158 for x64 - used in w8, w8.1 and in w10 up to est.build 14279
  • 0xb0 for 32 bit/0x160 for x64 - used in w10 up to est. build 16299
  • 0x10c for 32 bit/0x210 for x64 - used in w10 since est. build 17134
This struct has lots of pointer to functions (see also PiPnpRtlInit):

вторник, 14 января 2020 г.

using devm_kcalloc unchecked result in linux kernel

Part I
This time I add references to linux kernel github - although I ran my naive code analyzer on version 4.18 - all found bugs have long and happy life in current source tree

gb_generate_enum_strings in drivers/staging/greybus/audio_topology.c:
strings = devm_kcalloc(gb->dev, items, sizeof(char *), GFP_KERNEL);
data = gbenum->names;

for (i = 0; i < items; i++) {
  strings[i] = (const char *)data;


rt2880_pinmux_pins in drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c:  
p->func[i]->pins = devm_kcalloc(p->dev,
                p->func[i]->pin_count,
                sizeof(int),
                GFP_KERNEL);
for (j = 0; j < p->func[i]->pin_count; j++)
  p->func[i]->pins[j] = p->func[i]->pin_first + j;


Using unchecked result from devm_kmalloc_array:
ti_sci_scan_clocks_from_fw in drivers/clk/keystone/sci-clk.c:
tmp_clks = devm_kmalloc_array(dev, max_clks + 64,
                  sizeof(sci_clk),
                  GFP_KERNEL);
memcpy(tmp_clks, clks, max_clks * sizeof(sci_clk));


Doubtful case (I think is has delayed effects bcs no checks for ports field) - function mscc_ocelot_probe in drivers/net/ethernet/mscc/ocelot_board.c
ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
                     sizeof(struct ocelot_port *), GFP_KERNEL);

понедельник, 13 января 2020 г.

using devm_kzalloc unchecked result in linux kernel 4.18

Managed Device Resource (described in Documentation/driver-model/devres.txt) is witty technique for lazy developers. Unfortunately it does not exempt from the need to check results. I decided to see if there are such places in linux kernel (which can lead to null address dereference). Right way to do it is use Static Analyzer like clang, coverity or PVS Studio. But I am too lazy so I wrote simple and naive perl script and run it on linux kernel 4.18 source tree. It found 56 cases (from total 4173 where devm_kzalloc was used) - not too much for manual checking. So lets see what we have

impd1_probe in arch/arm/mach-integrator/impd1.c:
            lookup = devm_kzalloc(&dev->dev,
                          sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup),
                          GFP_KERNEL);
            chipname = devm_kstrdup(&dev->dev, devname, GFP_KERNEL);
            mmciname = kasprintf(GFP_KERNEL, "lm%x:00700", dev->id);
            lookup->dev_id = mmciname;



st_sensors_of_probe in drivers/iio/common/st_sensors/st_sensors_core.c (still not fixed):
    pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
    if (!of_property_read_u32(np, "st,drdy-int-pin", &val) && (val <= 2))
        pdata->drdy_int_pin = (u8) val;
    else
        pdata->drdy_int_pin = defdata ? defdata->drdy_int_pin : 0;

    pdata->open_drain = of_property_read_bool(np, "drive-open-drain");



sm501_register_gpio_i2c_instance in drivers/mfd/sm501.c:
    lookup = devm_kzalloc(&pdev->dev,
                  sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup),
                  GFP_KERNEL);
    lookup->dev_id = "i2c-gpio";
    if (iic->pin_sda < 32)
        lookup->table[0].chip_label = "SM501-LOW";
    else
        lookup->table[0].chip_label = "SM501-HIGH";
    lookup->table[0].chip_hwnum = iic->pin_sda % 32;
    lookup->table[0].con_id = NULL;
    lookup->table[0].idx = 0;
    lookup->table[0].flags = GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN;


rt2880_pinmux_index in drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c (still not fixed):
            f[c]->groups = devm_kzalloc(p->dev, sizeof(int), GFP_KERNEL);
            f[c]->groups[0] = i;


rt2880_pinmux_probe in drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c

        range = devm_kzalloc(p->dev, sizeof(struct pinctrl_gpio_range) + 4, GFP_KERNEL);
        range->name = name = (char *) &range[1];
        sprintf(name, "pio");
        range->npins = __be32_to_cpu(*ngpio);
        range->base = __be32_to_cpu(*gpiobase);
        range->pin_base = range->base;





rt5514_spi_pcm_probe in sound/soc/codecs/rt5514-spi.c:
    rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp),
            GFP_KERNEL);

    rt5514_dsp->dev = &rt5514_spi->dev;
    mutex_init(&rt5514_dsp->dma_lock);



rt5663_parse_dp in sound/soc/codecs/rt5663.c (still not fixed):
        rt5663->imp_table = devm_kzalloc(dev, table_size, GFP_KERNEL);
        device_property_read_u32_array(dev,
            "realtek,impedance_sensing_table",
            (u32 *)rt5663->imp_table, table_size);



perl script used to find this bugs:

пятница, 3 января 2020 г.

typos in "Linux Device Drivers Development"

I decided in retirement to fill the gaps in my education, so now I reading book "Linux Device Drivers Development" and noticed lots of annoying typos in code samples

page 65:
/* some where */
spinlock_t my_spinlock;
spin_lock_init(my_spinlock);
static irqreturn_t my_irq_handler(int irq, void *data)
{
 unsigned long status, flags;
 spin_lock_irqsave(&my_spinlock, flags);
 status = access_shared_resources();
 spin_unlock_irqrestore(&gpio->slock, flags); // wut? &
my_spinlock
 return IRQ_HANDLED;
}


page 103-104:
struct my_data {
 int my_int_var;
 struct tasklet_struct the_tasklet;
 int dma_request;
};


static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
  struct my_data *md = dev_id;
  /* Let's schedule our tasklet */
  tasklet_schedule(&md.dma_tasklet); // wut? &md->
the_tasklet
  return IRQ_HANDLED;
}

 
page 127:
/* Move the cursor ten time, relative from the beginning of the file */
if (lseek(fd, 7, SEEK_SET) < 0)
return 1;


An so on. Seems that code samples looks like Frankenstein ripped from some random kernel places

вторник, 19 ноября 2019 г.

last version of wincheck

it`s last because of
My former employer was so so nice that he allowed me to publish this build. Btw I seek new job

Download
Mirror

Changelog: 
  • add support of Windows 1909
  • add support of new RFG relocs. As usually kernel itself has bad IMAGE_DYNAMIC_RELOCATION_TABLE - it contains zero type somewhere inside IMAGE_DYNAMIC_RELOCATION
  • add dumping of WMI_LOGGER_CONTEXTs for InfinityHook detection (with -wmi option)
  • add dumping of PsAltSystemCallHandlers
  • add dumping of PoPdcCallbacks (with -pofx option)
  • add dumping of PpmPlatformStates (with -ppm option)
  • add dumping callbacks registered with RtlRegisterFeatureConfigurationChangeNotification function 

пятница, 15 ноября 2019 г.

kernel resource FUNCTIONEXTENTLIST

I commited today plugin for processing 64bit kernel resource with name "FUNCTIONEXTENTLIST" (located in RCDATA)

It seems that processing of this resource happens in huge unnamed sub called from famous KiFilterFiberContext, so this is apparently part of PatchGuard. Format of this resource relative simple.
At start we have signature CTXE for compressed data (LTXE for noncompressed but I have never seen this). Data unpacking with RtlDecompressBufferEx function. In packed data we have table with pair offsets, first to RUNTIME_FUNCTION recognised from IDA and second to some additional RUNTIME_FUNCTION (which usually skipped in IDA Pro for unknown reason)

And even after calling this plugin there are lots of some valid RUNTIME_FUNCTION in .pdata section - I don`t know why

четверг, 14 ноября 2019 г.