Typedef struct _ section_image_information {
Pvoid entrypoint;
Ulong stackzerobits;
Ulong stackreserved;
Ulong stackcommit;
Ulong imagesubsystem;
Word subsystemversionlow;
Word subsystemversionhigh;
Ulong unknown1;
Ulong imagecharacteristics;
Ulong imagemachinetype;
Ulong unknown2 [3];
} Section_image_information, * psection_image_information;
DWORD getdllfunctionaddress (char * lpfunctionname, punicode_string pdllname)
{
Handle hthread, hsection, hfile, hmod;
Section_image_information ⅱ;
Image_dos_header * dosheader;
Image_optional_header * opthdr;
Image_export_directory * pexporttable;
DWORD * arrayoffunctionaddresses;
DWORD * arrayoffunctionnames;
Word * arrayoffunctionordinals;
DWORD functionordinal;
DWORD base, X, functionaddress;
Char * functionname;
String ntfunctionname, ntfunctionnamesearch;
Pvoid baseaddress = NULL;
Size_t size = 0;
Object_attributes OA = {sizeof OA, 0, pdllname, obj_case_insensitive };
Io_status_block iosb;
// _ Asm int 3;
Zwopenfile (& hfile, file_execute | synchronize, & OA, & iosb, file_assist_read, file_synchronous_io_nonalert );
Oa. objectname = 0;
Zwcreatesection (& hsection, section_all_access, & OA, 0, page_execute, sec_image, hfile );
Zwmapviewofsection (hsection, ntcurrentprocess (), & baseaddress, 0, 1000, 0, & size, (section_inherit) 1, mem_top_down, page_readwrite );
Zwclose (hfile );
Hmod = baseaddress;
Dosheader = (image_dos_header *) hmod;
Opthdr = (image_optional_header *) (byte *) hmod + dosheader-> e_lfanew + 24 );
Pexporttable = (image_export_directory *) (byte *) hmod + opthdr-> datadirectory [image_directory_entry_export]. virtualaddress );
// Now we can get the exported functions, but note we convert from RVA to address
Arrayoffunctionaddresses = (DWORD *) (byte *) hmod + pexporttable-> addressoffunctions );
Arrayoffunctionnames = (DWORD *) (byte *) hmod + pexporttable-> addressofnames );
Arrayoffunctionordinals = (word *) (byte *) hmod + pexporttable-> addressofnameordinals );
Base = pexporttable-> base;
Rtlinitstring (& ntfunctionnamesearch, lpfunctionname );
For (x = 0; x <pexporttable-> numberoffunctions; X ++)
{
Functionname = (char *) (byte *) hmod + arrayoffunctionnames [x]);
Rtlinitstring (& ntfunctionname, functionname );
Functionordinal = arrayoffunctionordinals [x] + base-1; // always need to add base,-1 as array counts from 0
// This is the funny bit. You wowould perform CT the function pointer to simply be arrayoffunctionaddresses [x]
// Oh No Thats too simple. It is actually arrayoffunctionaddresses [functionordinal]!
Functionaddress = (DWORD) (byte *) hmod + arrayoffunctionaddresses [functionordinal]);
If (rtlcomparestring (& ntfunctionname, & ntfunctionnamesearch, true) = 0)
{
Zwclose (hsection );
Return functionaddress;
}
}
Zwclose (hsection );
Return 0;
}
This code can be used directly, for example: DWORD functionaddress;
Unicode_string dllname;
Rtlinitunicodestring (& dllname, l "\ device \ harddiskvolume1 \ Windows \ system32 \ NTDLL. dll ");
Functionaddress = getdllfunctionaddress ("zwcreateprocessex", & dllname );
Position = * (word *) (functionaddress + 1 ));
Dbuplint ("zwcreateprocessex's ID: % d \ n", position );
The above code loads NTDLL from the driver layer, and then finds the function address from the output table for hook-up.
For example, you can use hook zwcreateprocessex to monitor Process Creation and hook zwquerysysteminformation to hide processes.