For example driver Ucx01000.sys (USB host controller extension) contains functions table which I named UCXFUNCTIONS. I wrote simple IDC script to find and add this structure (in addition to ordinary WDFFUNCTIONS) in clients drivers of this extension
#include <idc.idc>
static add_struct(size)
{
auto id;
id = AddStrucEx(-1,"UCXFUNCTIONS",0);
if ( -1 == id )
id = GetStrucIdByName("UCXFUNCTIONS");
if ( -1 == id )
return -1;
AddStrucMember(id,"UcxIoDeviceControl", 0X0, 0x20000400, -1, 4);
AddStrucMember(id,"UcxControllerCreate", 0X4, 0x20000400, -1, 4);
AddStrucMember(id,"UcxControllerNeedsReset", 0X8, 0x20000400, -1, 4);
AddStrucMember(id,"UcxControllerResetComplete",0Xc, 0x20000400, -1, 4);
AddStrucMember(id,"UcxControllerSetFailed", 0X10, 0x20000400, -1, 4);
AddStrucMember(id,"UcxRootHubCreate", 0X14, 0x20000400, -1, 4);
AddStrucMember(id,"UcxRootHubPortChanged", 0X18, 0x20000400, -1, 4);
AddStrucMember(id,"UcxUsbDeviceCreate", 0X1c, 0x20000400, -1, 4);
AddStrucMember(id,"UcxUsbDeviceInitSetEventCallbacks", 0X20, 0x20000400, -1, 4);
AddStrucMember(id,"UcxUsbDeviceRemoteWakeNotification", 0X24, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointCreate", 0X28, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointGetStaticStreamsReferenced", 0X2c, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointNeedToCancelTransfers", 0X30, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointInitSetEventCallbacks", 0X34, 0x20000400, -1, 4);
AddStrucMember(id,"UcxDefaultEndpointInitSetEventCallbacks", 0X38, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointSetWdfIoQueue", 0X3c, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointPurgeComplete", 0X40, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointStartComplete", 0X44, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointAbortComplete", 0X48, 0x20000400, -1, 4);
AddStrucMember(id,"UcxEndpointNoPingResponseError", 0X4c, 0x20000400, -1, 4);
AddStrucMember(id,"UcxStaticStreamsSetStreamInfo", 0X50, 0x20000400, -1, 4);
AddStrucMember(id,"UcxStaticStreamsCreate", 0X54, 0x20000400, -1, 4);
return id;
}
static main(void)
{
auto data_start;
auto data_end;
auto idx;
// out data
auto wdf_size;
auto wdf_func;
data_end = data_start = BADADDR;
wdf_size = 0;
wdf_func = BADADDR;
// find .data section
for ( idx = FirstSeg(); idx != BADADDR; idx = NextSeg(idx) )
{
auto sname;
sname = SegName(idx);
if ( (strlen(sname) == 5) &&
strstr(sname, ".data") != 0
)
{
data_start = SegStart(idx);
data_end = SegEnd(idx);
break;
}
}
if ( data_start == BADADDR )
return;
// find "Ucx" unicode string in .data section
idx = data_start;
while(1)
{
auto addr, id;
idx = FindBinary(idx, SEARCH_DOWN, "55 00 63 00 78 00 00 00");
if ( idx == BADADDR )
break;
Message("found at %X\n", idx);
addr = DfirstB(idx);
if ( addr != BADADDR )
{
id = 0;
Message("ref from %X\n", addr);
wdf_size = Dword(addr + 0x14);
wdf_func = Dword(addr + 0x10);
if ( wdf_size != 0 )
{
id = add_struct(wdf_size);
}
if ( id != 0 )
{
auto ssize;
ssize = GetStrucSize(id);
MakeUnknown(wdf_func, ssize, 0);
if ( MakeData(wdf_func, FF_STRU, ssize, id) )
{
return;
}
Message("MakeData failed at %X, size %X\n", wdf_func, ssize);
}
}
idx = idx + 6; /* length of unicode string Ucx */
}
}
Комментариев нет:
Отправить комментарий