i found that these "heuristic anti-virus" based on the export function mentioned in one of jonnas article(btw:give my respect to jonna).
first i take a look at mcafee, it has a strange heuristic strategy. if it found an export symbol "keservicedescriptortable" ,while it didn`t found some normal driver function like "iocreatedevice", it report the virus. so i think the first method is to find the keservicedescriptortable dynamically.
with 90210s article "a more stable way to locate real kiservicetable"(http://www.rootkit.com/newsread.php?newsid=176) and his help, i can find the keservicedescriptortables servicetablebase, it is enough.(thank you 90210).
but i find nod32 is more restrice, it will detect zw* function and reported your driver as virus. so i must find a more common ways to locate export functions and symbols. fortunately i found some pieces in from sven b. schreiber. this book is cool!! the code is here:
pvoid spymemorycreate (dword dsize)
{
return exallocatepoolwithtag (pagedpool, max (dsize, 1),
spy_tag);
}
// -----------------------------------------------------------------
pvoid spymemorydestroy (pvoid pdata)
{
if (pdata != null) exfreepool (pdata);
return null;
}
// ==============================================================
// module info management
// =================================================================
pmodule_list spymodulelist (pdword pddata,
pntstatus pns)
{
dword dsize;
dword ddata = 0;
ntstatus ns = status_invalid_parameter;
pmodule_list pml = null;
for (dsize = page_size; (pml == null) && dsize; dsize <<= 1)
{
if ((pml = spymemorycreate (dsize)) == null)
{
ns = status_no_memory;
break;
}
ns = zwquerysysteminformation (systemmoduleinformation,
pml, dsize, &ddata);
if (ns != status_success)
{
pml = spymemorydestroy (pml);
ddata = 0;
if (ns != status_info_length_mismatch) break;
}
}
if (pddata != null) *pddata = ddata;
if (pns != null) *pns = ns;
return pml;
}
// -----------------------------------------------------------------
pmodule_list spymodulefind (pbyte pbmodule,
pdword pdindex,
pntstatus pns)
{
dword i;
dword dindex = -1;
ntstatus ns = status_invalid_parameter;
pmodule_list pml = null;
if ((pml = spymodulelist (null, &ns)) != null)
{
for (i = 0; i < pml->dmodules; i++)
{
if (!_stricmp (pml->amodules [i].abpath +
pml->amodules [i].wnameoffset,
pbmodule))
{
dindex = i;
break;
}
}
if (dindex == -1)
{
pml = spymemorydestroy (pml);
ns = status_no_such_file;
}
}
if (pdindex != null) *pdindex = dindex;
if (pns != null) *pns = ns;
return pml;
}
// -----------------------------------------------------------------
pvoid spymodulebase (pbyte pbmodule,
pntstatus pns)
{
pmodule_list pml;
dword dindex;
ntstatus ns = status_invalid_parameter;
pvoid pbase = null;
if ((pml = spymodulefind (pbmodule, &dindex, &ns)) != null)
{
pbase = pml->amodules [dindex].pbase;
spymemorydestroy (pml);
}
if (pns != null) *pns = ns;
return pbase;
}
// -----------------------------------------------------------------
pimage_nt_headers spymoduleheader (pbyte pbmodule,
pvoid *ppbase,
pntstatus pns)
{
pvoid pbase = null;
ntstatus ns = status_invalid_parameter;
pimage_nt_headers pinh = null;
if (((pbase = spymodulebase (pbmodule, &ns)) != null) &&
((pinh = rtlimagentheader (pbase)) == null))
{
ns = status_invalid_image_format;
}
if (ppbase != null) *ppbase = pbase;
if (pns != null) *pns = ns;
return pinh;
}
// -----------------------------------------------------------------
pimage_export_directory spymoduleexport (pbyte pbmodule,
pvoid *ppbase,
pntstatus pns)
{
pimage_nt_headers pinh;
pimage_data_directory pidd;
pvoid pbase = null;
ntstatus ns = status_invalid_parameter;
pimage_export_directory pied = null;
if ((pinh = spymoduleheader (pbmodule, &pbase, &ns)) != null)
{
pidd = pinh->optionalheader.datadirectory
+ image_directory_entry_export;
if (pidd->virtualaddress &&
(pidd->size >= image_export_directory_))
{
pied = ptr_add (pbase, pidd->virtualaddress);
}
else
{
ns = status_data_error;
}
}
if (ppbase != null) *ppbase = pbase;
if (pns != null) *pns = ns;
return pied;
}
// -----------------------------------------------------------------
pvoid spymodulesymbol (pbyte pbmodule,
pbyte pbname,
pvoid *ppbase,
pntstatus pns)
{
pimage_export_directory pied;
pdword pdnames, pdfunctions;
word *pwordinals;
dword i, j;
pvoid pbase = null;
ntstatus ns = status_invalid_parameter;
pvoid paddress = null;
if ((pied = spymoduleexport (pbmodule, &pbase, &ns)) != null)
{
pdnames = ptr_add (pbase, pied->addressofnames);
pdfunctions = ptr_add (pbase, pied->addressoffunctions);
pwordinals = ptr_add (pbase, pied->addressofnameordinals);
for (i = 0; i < pied->numberofnames; i++)
{
j = pwordinals [i];
if (!strcmp (ptr_add (pbase, pdnames [i]), pbname))
{
if (j < pied->numberoffunctions)
{
paddress = ptr_add (pbase, pdfunctions [j]);
}
break;
}
}
if (paddress == null)
{
ns = status_procedure_not_found;
}
}
if (ppbase != null) *ppbase = pbase;
if (pns != null) *pns = ns;
return paddress;
}
// -----------------------------------------------------------------
pvoid spymodulesymbolex (pbyte pbsymbol,
pvoid *ppbase,
pntstatus pns)
{
dword i;
byte abmodule [maximum_filename_length] = "ntoskrnl.exe";
pbyte pbname = pbsymbol;
pvoid pbase = null;
ntstatus ns = status_invalid_parameter;
pvoid paddress = null;
for (i = 0; pbsymbol [i] && (pbsymbol [i] != !); i++);
if (pbsymbol [i++])
{
if (i <= maximum_filename_length)
{
memcpy (abmodule, pbsymbol, i);
pbname = pbsymbol + i;
}
else
{
pbname = null;
}
}
if (pbname != null)
{
paddress = spymodulesymbol (abmodule, pbname, &pbase, &ns);
}
if (ppbase != null) *ppbase = pbase;
if (pns != null) *pns = ns;
return paddress;
}
so now we can get symbol like this:
pkeservicedescriptortable = spymodulesymbolex("keservicedescriptortable", null, &ns);
cool!
文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




