阅读:1891回复:14
公布研究结果-搜索WinExec地址
/*
* 在kern32.dll中搜索指定API地址 * Hash(WinExec) = 0x72dc Hash(LoadLibraryA) = 0xae14 */ ULONG SearchApi(WORD api_hash) { //搜索k32dll的API地址 PEPROCESS pSystemProcess = PsGetCurrentProcess(); //make sure you are running at IRQL PASSIVE_LEVEL PLIST_ENTRY pCurrentList = (PLIST_ENTRY)((PUCHAR)pSystemProcess + 0xA0); PLIST_ENTRY pTempList = pCurrentList; PEPROCESS pEProcess = NULL; do { PPEB peb = NULL; PUCHAR lpname = NULL; pEProcess = (PEPROCESS)((PUCHAR)pTempList - 0xA0); peb = (PPEB)(*(PULONG)((PUCHAR)pEProcess + 0x1b0)); lpname = (PUCHAR)pEProcess + 0x1fc; KdPrint(("%s\n", lpname)); if ((peb != NULL) && (strncmp(lpname, "winlogon", 8) == 0)) { ULONG api_addr = 0; KeAttachProcess((PKPROCESS)pEProcess); KdPrint(("ImageBaseAddress:%08x\n", peb->ImageBaseAddress)); _asm { mov eax, peb; mov eax, [eax+0x0c];//ldr mov esi, [eax+0x1c];//esi->ldr.InInitializationOrderMoudleList _LIST_ENTRY struct lodsd; //eax = [esi]; mov ebx, [eax+0x08];//k32dll is the first! and baseaddress is follow _LIST_ENTRY //now get pe image infos to find LoadLibrary and GetProcAddress API //assert ebx is the pe image base!!! mov ax, api_hash; //Hash(LoadLibraryA) = 0xae14 //Hash(WinExec) = 0x72dc //call search_api; //mov [ebp-4], eax; //this is LoadLibraryA API //------------------------------------------------------------------------------ //ebx-PE Image Base,eax-hash of api name, return eax!!! //------------------------------------------------------------------------------ //search_api: mov edx, eax; mov eax, [ebx+0x3c]; //File address of the new exe header mov eax, [eax+ebx+0x78]; //pe base ->data directory[16] add eax, ebx; //get directory[0] Address ->export table ->eax mov esi, [eax+0x20]; //get export funs names rva add esi, ebx; //esi->export names table address //mov ecx, [eax+0x18]; //get export funs numbers xor ecx, ecx; //search funs name tables next_api: mov edi, [esi+ecx*4]; // add edi, ebx; //----------------------------------- //计算[edi]字符串的hash值 //----------------------------------- pushad; xor eax, eax; cacul_next: shl eax, 2; movzx ecx, byte ptr[edi]; add ax, cx; inc edi; inc ecx; loop cacul_next; //test edx!!! cmp ax, dx; jz search_end; popad; inc ecx; jmp next_api; search_end: popad; //ecx is the GetProcAdress index mov eax, [eax+0x1c]; add eax, ebx; mov eax, [eax+4*ecx]; add eax, ebx; mov api_addr, eax; //ret; } KdPrint(("%08x\n", api_addr)); KeDetachProcess(); return api_addr; } pTempList = pTempList->Flink; } while(pCurrentList != pTempList); return 0; } 注意!仍然存在硬编码(主要是操作系统的EProcess数据结构各操作系统有变化) |
|
沙发#
发布于:2008-04-02 10:19
直接在Apc里面搜索就可以了啊~~晕~
|
|
|
板凳#
发布于:2008-04-02 10:51
老V啊!!!可否告诉我怎么弄啊?对APC不怎么熟悉,我想得到
Winexec的地址,然后想在驱动里面启动一个进程啊 |
|
地板#
发布于:2008-04-02 16:43
硬编码的话,你还不如直接用那个例子里的东西,针对所有的OS硬编码,还节省空间.
|
|
|
地下室#
发布于:2008-04-02 17:19
主要是kernel32的变动比较多,内核数据结构相对稳定一点,我机器上两个2000的地址都不一样:-(
wowocock有没有什么好的办法啊?我郁闷 |
|
5楼#
发布于:2008-04-02 17:41
你的方法也行,只要稳定即可.
|
|
|
6楼#
发布于:2008-04-02 22:13
顺便公布一下测试操作的代码,该办法比PsGetVersion管用:-)PsGetVersion居然无法确定Windows2003 5.2.3790.0 和Windows2003 SP1 5.2.3790.1830
基于我假定EPROCESS数据结构变化,则EPROCESS中的镜像文件偏移必然变化的前提!!!希望大家帮我完善下 #define BASE_PROCESS_NAME_OFFSET_2K 0x01FC//NT5.0.2195.7133 #define BASE_PROCESS_NAME_OFFSET_XP 0x0174//NT5.1.2600.3093 #define BASE_PROCESS_NAME_OFFSET_2K3 0x0154//nt5.2.3790.0 #define BASE_PROCESS_NAME_OFFSET_2K3_SP1 0x0164//nt5.2.3790.1830 #define BASE_PROCESS_NAME_OFFSET_VISTA 0x014c WORD GetWindowsVersion() { PEPROCESS pSystemProcess = PsGetCurrentProcess(); WORD offset; for (offset=0; offset < PAGE_SIZE; offset++) { if(strncmp("System", (PCHAR)pSystemProcess + offset, 6) == 0) { g_EProcessOffset.wOffsetName = offset; KdPrint(("%08x", offset)); switch (offset) { case BASE_PROCESS_NAME_OFFSET_2K: KdPrint(("WINDOWS_VERSION_2K\n")); return WINDOWS_VERSION_2K; break; case BASE_PROCESS_NAME_OFFSET_XP: KdPrint(("WINDOWS_VERSION_XP\n")); return WINDOWS_VERSION_XP; break; case BASE_PROCESS_NAME_OFFSET_2K3: KdPrint(("WINDOWS_VERSION_2K3\n")); return WINDOWS_VERSION_2K3; break; case BASE_PROCESS_NAME_OFFSET_2K3_SP1: KdPrint(("WINDOWS_VERSION_2K3_SP1\n")); return WINDOWS_VERSION_2K3_SP1; break; case BASE_PROCESS_NAME_OFFSET_VISTA: KdPrint(("WINDOWS_VERSION_VISTA\n")); return WINDOWS_VERSION_VISTA; break; default: return WINDOWS_VERSION_NONE; } } } return WINDOWS_VERSION_NONE; } |
|
7楼#
发布于:2008-04-03 16:23
论坛上有个现成的啊~~
|
|
|
8楼#
发布于:2008-04-03 17:10
The RTL_OSVERSIONINFOW structure is used with RtlGetVersion.
typedef struct _OSVERSIONINFOW { ULONG dwOSVersionInfoSize; ULONG dwMajorVersion; ULONG dwMinorVersion; ULONG dwBuildNumber; ULONG dwPlatformId; WCHAR szCSDVersion[ 128 ]; // Maintenance string for PSS usage} RTL_OSVERSIONINFOW;Members dwOSVersionInfoSize Specifies the size in bytes of an RTL_OSVERSIONINFOW structure. This member must be set before the structure is used with RtlGetVersion. dwMajorVersion Identifies the major version number of the operating system. For example, for Windows NT version 4.0 the major version number is four, and for Windows 2000 the major version number is five. dwMinorVersion Identifies the minor version number of the operating system. For example, for Windows 2000 the minor version number is zero. dwBuildNumber Identifies the build number of the operating system. dwPlatformId Identifies the operating system platform. For Microsoft Win32 on NT-based operating systems, RtlGetVersion returns the value VER_PLATFORM_WIN32_NT. szCSDVersion Contains a null-terminated string, such as "Service Pack 3", which indicates the latest Service Pack installed on the system. If no Service Pack has been installed, the string is empty. |
|
|
9楼#
发布于:2008-04-03 18:59
我测试RtlGetVersion不行,只能得到buildnum,zCSDVersion总是得到空啊
所以无法区别win2003和win2003SP1因为buildnum是一样的 现成的是硬编码的,我现在的基本可以正常工作了 |
|
10楼#
发布于:2008-04-03 19:16
windows2003SP1机器上KeInsertQueueApc老是失败!!!
//...and queue it if (!KeInsertQueueApc(pApc, 0, NULL, 0)) { DbgPrint("KernelExec -> Failed to insert APC"); 但是同样的代码在2K和XP上运行很正常啊,wowowowowocock提示一下啊,会是什么原因啊 |
|
11楼#
发布于:2008-04-03 19:35
我靠,居然是windows2003的DEP(数据执行保护)造成的,我关闭该功能后,即可正常工作,看来windows2003是安全很多啊
看来得先在其进程里面分配空间,然后将代码copy过去才行啊 |
|
12楼#
发布于:2008-04-23 00:06
好东西,学习了!谢谢!
|
|
13楼#
发布于:2008-04-23 09:01
驱动中启动一个进程,怎么看都不正常。
|
|
14楼#
发布于:2008-05-07 07:03
Ring3 shellcode可以多中多样~~
|
|
|