概述
采用FS去定位API地址:
FS寄存器指向当前活动线程的TEB结构(线程结构)
偏移 说明
000 指向SEH链指针
004 线程堆栈顶部
008 线程堆栈底部
00C SubSystemTib
010 FiberData
014 ArbitraryUserPointer
018 FS段寄存器在内存中的镜像地址
020 进程PID
024 线程ID
02C 指向线程局部存储指针
030 PEB结构地址(进程结构)
034 上个错误号
mov eax,fs:[0x18] ; 获得当前线程的TEB地址
mov eax,[eax+0x30] ; 在TEB偏移30h获得PEB地址
TIB+18h 是TIB的反身指针 指向PEB的首地址 因此可省略而直接使用fs:[30h] 得到自己进程的PEB
从XP SP2 引入 不同进程的PEB地址会不一样 所以不能用 本进程的FS:[28H] 的指针去读取其他进程的内容
如果是用这种方式去获得PEB的话 还要去循环验证是否为 kernel32.dll
mov eax,fs:[0x18] //获得FS段寄存器在内存中的镜像地址,即TEB的地址
mov pTeb,eax
所以不采用这种方式 在 计算机病毒揭秘 中 去寻找API地址 采用 先找 kernel32.dll 在去找API地址
FS:0指向线程环境块TEB;
FS:[0]指向当前线程的结构化异常处理结构(SEH);
FS:0指向TEB的理解应该是:
TEB结构存放于FS段从0开始的位置,整个TEB结构数据在FS段中;
FS:[0]指向当前线程的结构化异常处理结构的理解应该是:
在FS:0所指向的TEB结构中,第一个元素指向当前线程的结构化异常处理结构,而这个结构存在与DS段中;
部分TEB如下:
ntdll!_TEB
struct _TEB, 66 elements, 0xfb8 bytes
+0x000 NtTib : struct _NT_TIB, 8 elements, 0x1c bytes
+0x000 ExceptionList : Ptr32 to struct _EXCEPTION_REGISTRATION_RECORD,2 elements, 0x8 bytes
+0x000 Next : Ptr32 to struct _EXCEPTION_REGISTRATION_RECORD, 2 elements, 0x8 bytes
+0x004 Handler : Ptr32 to _EXCEPTION_DISPOSITION
+0x004 StackBase : Ptr32 to Void
+0x008 StackLimit : Ptr32 to Void
+0x00c SubSystemTib : Ptr32 to Void
+0x010 FiberData : Ptr32 to Void
+0x010 Version : Uint4B
...........................................
............................................
而下面两条指令可以看出其差异吧:
MOV EAX,FS:0==>EAX=0 (SoftICE中)
MOV EAX,FS:[0]==>EAX=指向SEH的指针,如0x0012FFB0
fs:0表示的是fs段中偏移量0这个地址,从这个地址开始储存的就是TEB,程序中不能直接使用fs:0(有些编译器会将其解释为fs:[0])。
fs:[0]表示的是fs:0这个地址中储存的数据,TEB中的第1个成员就是SEH指针。
在 masm32 中,fs:0 和 fs:[0] 是完全相同的。 在用之前 用 assume fs:nothing编译器不同导致
下面是通过扫描 kernel32.dll获得 MessageBoxA ExitProcess LoadLibraryA 函数地址 当然 我们可以修改其中的digest 找到 LoadLibraryA 和 GetProcaddress 地址例子:
int main()
{
_asm{
nop
nop
nop
nop
nop
CLD ; clear flag DF
;store hash
push 0x1e380a6a ;hash of MessageBoxA
push 0x4fd18963 ;hash of ExitProcess
push 0x0c917432 ;hash of LoadLibraryA 这里添加你想要的函数 EG: LoadLibraryA GetProcaddress 最后在[EDI-0xX]就是函数的地址
mov esi,esp ; esi = addr of first function hash
lea edi,[esi-0xc] ; edi = addr to start writing function
; make some stack space
xor ebx,ebx
mov bh, 0x04
sub esp, ebx
; push a pointer to "user32" onto stack
mov bx, 0x3233 ; rest of ebx is null
push ebx
push 0x72657375
push esp
xor edx,edx
; find base addr of kernel32.dll
mov ebx, fs:[edx + 0x30] ; ebx = address of PEB
mov ecx, [ebx + 0x0c] ; ecx = pointer to loader data
mov ecx, [ecx + 0x1c] ; ecx = first entry in initialisation order list
mov ecx, [ecx] ; ecx = second entry in list (kernel32.dll)
mov ebp, [ecx + 0x08] ; ebp = base address of kernel32.dll
find_lib_functions:
lodsd ; load next hash into al and increment esi
cmp eax, 0x1e380a6a ; hash of MessageBoxA - trigger
; LoadLibrary("user32")
jne find_functions
xchg eax, ebp ; save current hash
call [edi - 0x8] ; LoadLibraryA
xchg eax, ebp ; restore current hash, and update ebp
; with base address of user32.dll
find_functions:
pushad ; preserve registers
mov eax, [ebp + 0x3c] ; eax = start of PE header
mov ecx, [ebp + eax + 0x78] ; ecx = relative offset of export table
add ecx, ebp ; ecx = absolute addr of export table
mov ebx, [ecx + 0x20] ; ebx = relative offset of names table
add ebx, ebp ; ebx = absolute addr of names table
xor edi, edi ; edi will count through the functions
next_function_loop:
inc edi ; increment function counter
mov esi, [ebx + edi * 4] ; esi = relative offset of current function name
add esi, ebp ; esi = absolute addr of current function name
cdq ; dl will hold hash (we know eax is small)
hash_loop:
movsx eax, byte ptr[esi]
cmp al,ah
jz compare_hash
ror edx,7
add edx,eax
inc esi
jmp hash_loop
compare_hash:
cmp edx, [esp + 0x1c] ; compare to the requested hash (saved on stack from pushad)
jnz next_function_loop
mov ebx, [ecx + 0x24] ; ebx = relative offset of ordinals table
add ebx, ebp ; ebx = absolute addr of ordinals table
mov di, [ebx + 2 * edi] ; di = ordinal number of matched function
mov ebx, [ecx + 0x1c] ; ebx = relative offset of address table
add ebx, ebp ; ebx = absolute addr of address table
add ebp, [ebx + 4 * edi] ; add to ebp (base addr of module) the
; relative offset of matched function
xchg eax, ebp ; move func addr into eax
pop edi ; edi is last onto stack in pushad
stosd ; write function addr to [edi] and increment edi
push edi
popad ; restore registers
; loop until we reach end of last hash
cmp eax,0x1e380a6a
jne find_lib_functions
function_call:
xor ebx,ebx
push ebx // cut string
push 0x74736577
push 0x6C696166 //push failwest
mov eax,esp //load address of failwest
push ebx
push eax
push eax
push ebx
call [edi - 0x04] ; //call MessageboxA
push ebx
call [edi - 0x08] ; // call ExitProcess
nop
nop
nop
nop
}
}
转载于:https://www.cnblogs.com/zcc1414/p/3982545.html
最后
以上就是无辜小笼包为你收集整理的定位API地址学习的全部内容,希望文章能够帮你解决定位API地址学习所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复