获取kernel32基地址

从InMemoryOrderModuleList地址上获取kernel32.dll的基地址,原理如下:

1
2
3
4
5
6
7
xor ebx, ebx 
mov ebx, fs:[ 0x30 ] ;PEB
mov ebx, [ ebx + 0x0C ] ;PEB->Ldr
mov ebx, [ ebx + 0x14 ] ;PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
mov ebx, [ ebx ] ;next entry (2nd entry)
mov ebx, [ ebx ] ;entry (3rd entry)
mov ebx, [ ebx + 0x10 ] ;base address (kernel32.dll)

获取kernel32基地址以后,就可以从EAT获取GetProcAddress地址以及其他函数地址,下面程序以获得FindFirstFile地址为例,在EAT中搜索FindFirstFile地址的时候没有采用直接比较字符串名称的方法,而是对字符串名称作运算,根据运算结果来进行比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include<stdio.h>
#include<Windows.h>

#define win10x64 1

#ifdef win10x64
#define kernel32Value 0x6E2BCA17
#elif defined(win7x64)
#define kernel32Value 0x8FECD63F
#endif


typedef HANDLE (*myFindFirstFile)(LPCTSTR lpFileName,LPWIN32_FIND_DATA lpFindFileData);

DWORD findPEB()
{
DWORD pebValue;
__asm
{
mov eax,fs:[0x30]
mov pebValue,eax
}
return pebValue;
}

DWORD calValue1(WORD *a1)
{
DWORD v1,v3;
v3 = 0;
while(*a1)
{
v1 = (WORD)*a1;
++a1;
v3 = v1 + ((v3 << 19) | ((unsigned __int64)v3 >> 13));
}
return v3;
}

DWORD calValue2(BYTE *a1)
{
DWORD v1,v3;
v3 = 0;
while(*a1)
{
v1 = *a1++;
v3 = v1 + ((v3 << 19) | ((unsigned __int64)v3 >> 13));
}
return v3;
}

DWORD findKernel32()
{
DWORD pebValue = findPEB();

DWORD v1 = *(DWORD *)(pebValue + 12);
DWORD *v3 = *(DWORD **)(v1 + 20);
DWORD *v4 = *(DWORD **)(v1 + 20);
do
{
if(calValue1((WORD *)v3[10]) == kernel32Value)
{
return v3[4];
}
v3 = (DWORD *)*v3;
} while (v3 && v3 != v4);
return -1;
}

DWORD findGetProcAddress(DWORD kernel32Addr,DWORD funcValue)
{
DWORD exportTable,addressOfFunctions,addressOfNames,addressOfNameOrdinals,numberOfNames;
exportTable = (*(DWORD *)(*(DWORD *)(kernel32Addr + 60) + kernel32Addr + 120) + kernel32Addr);
addressOfFunctions = *(DWORD *)(exportTable + 0x1c) + kernel32Addr;
addressOfNames = *(DWORD *)(exportTable + 0x20) + kernel32Addr;
addressOfNameOrdinals = *(DWORD *)(exportTable + 0x24) + kernel32Addr;

numberOfNames = *(DWORD *)(exportTable + 0x18);
for(int i=0;i<numberOfNames;i++)
{
if(calValue2((BYTE *)(*(DWORD *)(addressOfNames + 4 * i) + kernel32Addr)) == funcValue)
return *(DWORD *)(addressOfFunctions + 4 * *(WORD *)(addressOfNameOrdinals + 2 * i)) + kernel32Addr;
}
return 0;
}

int main(int argc,char *argv[])
{
DWORD kernel32Addr;
myFindFirstFile findFirstFileAddr;
kernel32Addr = findKernel32();
printf("kernel32Addr:%X\n",kernel32Addr);
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
printf("hKernel32:%X\n",hKernel32);
findFirstFileAddr = (myFindFirstFile)findGetProcAddress(kernel32Addr,0x63D6C065);
printf("findFirstFileAddr:%p\n",findFirstFileAddr);
printf("FindFirstFile:%p\n",GetProcAddress(hKernel32,"FindFirstFileA"));
system("pause");
return 0;
}