PEB获取GetProcAddrees函数地址
1.fs寄存器指向TEB结构
2.在TEB+0x30地方指向PEB结构
3.在PEB+0x0C地方指向PEB_LDR_DATA结构
4.在PEB_LDR_DATA+0x1C地方就是一些动态连接库地址了,如第一个指向ntdll.dll,第二个就是kernel32.dll的地址。
其结构示意图如图
利用PEB查找kernerl32地址的汇编实现
mov eax, fs:0x30 ;PEB的地址
mov eax, [eax + 0x0c] ;Ldr的地址
mov esi, [eax + 0x1c] ;Flink地址
lodsd
mov eax, [eax + 0x08] ;eax就是kernel32.dll的地址
这样就获得了kernel32.dll的基址了,其实就相当于调用LoadLibrary的返回值,可以在GetProcAddress里面直接使用
然后我们要做的事就是查找导出表,找到GetprocAddress的地址
mov ebp, 0x77E40000 ;kernel32.dll 基址
mov eax, [ebp+3Ch] ;eax = PE首部
mov edx,[ebp+eax+78h]
add edx,ebp ;edx = 引出表地址
mov ecx , [edx+18h] ;ecx = 输出函数的个数
mov ebx,[edx+20h]
add ebx, ebp ;ebx =函数名地址,AddressOfName
search:
dec ecx
mov esi,[ebx+ecx*4]
add esi,ebp ;依次找每个函数名称
;GetProcAddress
mov eax,0x50746547
cmp [esi], eax; 'PteG'
jne search
mov eax,0x41636f72
cmp [esi+4],eax; 'Acor'
jne search
;如果是GetProcA,表示找到了
mov ebx,[edx+24h]
add ebx,ebp ;ebx = 序号数组地址,AddressOf
mov cx,[ebx+ecx*2] ;ecx = 计算出的序号值
mov ebx,[edx+1Ch]
add ebx,ebp ;ebx=函数地址的起始位置,AddressOfFunction
mov eax,[ebx+ecx*4]
add eax,ebp ;利用序号值,得到出GetProcAddress的地址
好了,要做的事已经做了。总结一下
a. 通过TEB/PEB获取kernel32.dll基址
b. 在(基址+0x3c)处获取e_lfanewc就是PE标志。
c. 在(基址+e_lfanew+0x78)处获取引出表地址(后面为描述方便简称export)
d. 在(基址+export+0x1c)处获取AddressOfFunctions、AddressOfNames、AddressOfNameOrdinalse。
e. 搜索AddressOfNames,确定“GetProcAddress”所对应的index
f. index = AddressOfNameOrdinalse [ index ];
g. 函数地址 = AddressOfFunctions [ index ];