【汇编】通过汇编获得GetProcAddress函数地址
本帖最后由 wushaominkk 于 2018-8-2 14:39 编辑.386
.model flat,stdcall
option casemap:none
.code
main:
push ebp
mov ebp,esp
sub esp,10h
;------------------------------------------------------
;mov ebx,fs: ;进入OEP的时候,ebx默认是PEB
mov ebx,
mov ebx,
mov ebx,
mov ebx,
mov ebx, ;Ebx = kernel32.dll模块基址
mov eax, ;Eax = NtHeader offset
add eax,ebx ;NtHeader offset=>VA
mov eax, ;Eax = 导出表RVA
add eax,ebx ;导出表RVA=>VA
mov edx, ;Edx = 名称表RVA
add edx,ebx ;名称表RVA=>VA
xor ecx,ecx ;Ecx清零
MyLoop:
mov esi,;Esi = 函数名RVA
add esi,ebx ;函数名RVA=>VA
inc ecx ;Ecx++
;03 7
;GetProcAddress
movzx edi,byte ptr ;取函数名第0个字节
cmp edi,'G';如果等于ZF会被置为1
jnz MyLoop ;ZF为0则跳转
movzx edi,byte ptr ;取函数名第3个字节
cmp edi,'P'
jnz MyLoop
movzx edi,byte ptr ;取函数名第7个字节
cmp edi,'A'
jnz MyLoop
;到了这,说明已经找到了GetProcAddress在名称表中的位置了
;注意:Ecx现在等于真正的下标+1,而不是真正的下标
dec ecx ;Ecx减一,才是真正的下标
mov edx, ;Edx = 序号表RVA
add edx,ebx ;序号表RVA=>VA
movzx ecx,word ptr ;通过序号表找到地址表下标
mov edx, ;Edx = 地址表RVA
add edx,ebx ;地址表RVA=>VA
mov esi, ;函数RVA
add esi,ebx ;函数RVA=>VA
mov ,ebx;保存kernel32.dll模块基址
mov ,esi;保存GetProcAddress函数地址
call PushStr1 ;将下面的数据入栈
db "LoadLibraryA",0 ;参数2
PushStr1:
push ;参数1
call dword ptr ;GetProcAddress
mov ,eax ;保存LoadLibraryA函数地址
call PushStr2 ;将下面的数据入栈
db "user32.dll",0 ;参数1
PushStr2:
call eax ;LoadLibraryA
mov ,eax ;保存user32.dll模块基址
;------------------------------------------------------
add esp,10h
pop ebp
ret
end main
版本2
.386
.model flat,stdcall
option casemap:none
assume fs:nothing
;[+0] 本模块实例句柄
;[+4] kernel32.dll 模块基址
;[+8] GetProcAddress 函数地址
;[+0Ch] LoadLibraryA 函数地址
;[+10h] user32.dll 模块基址
.code
main:
push ebp
mov ebp,esp
call GetGlobal
mov edi,eax
;----------------------------------------------
;mov ebx,fs:
mov ebx,
mov ebx,
mov edx,
mov ,edx ;[+0]保存本模块实例句柄
mov ebx,
mov ebx,
mov ebx,
mov ,ebx ;[+4]保存kernel32.dll模块基址
mov eax, ;取Nt头文件偏移
add eax,ebx ;offset=>VA
mov eax, ;取导出表RVA
add eax,ebx ;RVA=>VA
mov edx, ;取名称表RVA
add edx,ebx ;RVA=>VA
xor ecx,ecx ;ecx清零
MyLoop:
mov esi, ;取函数名RVA
add esi,ebx ;RVA=>VA
inc ecx ;ecx++
cmp byte ptr,'G' ;如果等于ZF会被置为1
jnz MyLoop ;ZF为0则跳转
cmp byte ptr,'P'
jnz MyLoop
cmp byte ptr,'A'
jnz MyLoop
dec ecx ;ecx-- 真正的下标
mov edx, ;取序号表RVA
add edx,ebx ;RVA=>VA
mov cx,;通过序号表找到地址表下标
mov edx, ;取地址表RVA
add edx,ebx ;RVA=>VA
mov esi, ;取函数RVA
add esi,ebx ;RVA=>VA
mov ,esi ;保存GetProcAddress函数地址
call PushStr1 ;将下面的数据地址入栈
db "LoadLibraryA",0 ;参数2:要获取的函数名
PushStr1:
push ebx ;参数1:kernel32.dll模块基址
call esi ;GetProcAddress
mov ,eax ;保存LoadLibraryA函数地址
call PushStr2 ;将下面的数据地址入栈
db "user32.dll",0 ;参数1:需要Load的DLL名称
PushStr2:
call eax ;LoadLibraryA
mov ,eax ;保存user32.dll模块基址
;----------------------------------------------
pop ebp
ret
GetGlobal:
mov eax,
and eax,0FFFFF000h
add eax,200h
ret
end main
加强版:
.386
.model flat,stdcall
option casemap:none
assume fs:nothing
;[+0] 本模块实例句柄
;[+4] kernel32.dll 模块基址
;[+8] GetProcAddress 函数地址
;[+0Ch] LoadLibraryA 函数地址
;[+10h] user32.dll 模块基址
;[+14h] ClassName
;[+18h]~[+3Ch] WNDCLASSA结构体
;[+40h] RegisterClassA 函数地址
;[+44h] DefWindowProcA 函数地址
;[+48h] CreateWindowExA 函数地址
;[+4Ch] GetMessageA 函数地址
;[+50h] DispatchMessageA函数地址
;[+54h]~[+60h] MSG 结构体
;[+64h] 窗口句柄
.code
main:
push ebp
mov ebp,esp
call GetGlobal
mov edi,eax
;----------------------------------------------------
;mov ebx,fs:
mov ebx,
mov ebx,
mov edx,
mov ,edx ;[+0]保存本模块实例句柄
mov ebx,
mov ebx,
mov ebx,
mov ,ebx ;[+4]保存kernel32.dll模块基址
mov eax, ;取Nt头文件偏移
add eax,ebx ;offset=>VA
mov eax, ;取导出表RVA
add eax,ebx ;RVA=>VA
mov edx, ;取名称表RVA
add edx,ebx ;RVA=>VA
xor ecx,ecx ;ecx清零
MyLoop:
mov esi, ;取函数名RVA
add esi,ebx ;RVA=>VA
inc ecx ;ecx++
cmp byte ptr,'G' ;如果等于ZF会被置为1
jnz MyLoop ;ZF为0则跳转
cmp byte ptr,'P'
jnz MyLoop
cmp byte ptr,'A'
jnz MyLoop
dec ecx ;ecx-- 真正的下标
mov edx, ;取序号表RVA
add edx,ebx ;RVA=>VA
mov cx,;通过序号表找到地址表下标
mov edx, ;取地址表RVA
add edx,ebx ;RVA=>VA
mov esi, ;取函数RVA
add esi,ebx ;RVA=>VA
mov ,esi ;保存GetProcAddress函数地址
call PushStr1 ;将下面的数据地址入栈
db "LoadLibraryA",0 ;参数2:要获取的函数名
PushStr1:
push ebx ;参数1:kernel32.dll模块基址
call esi ;GetProcAddress
mov ,eax ;保存LoadLibraryA函数地址
call PushStr2 ;将下面的数据地址入栈
db "user32.dll",0 ;参数1:需要Load的DLL名称
PushStr2:
call eax ;LoadLibraryA
mov ,eax ;保存user32.dll模块基址
mov dword ptr,434241h ;ClassName "ABC"
mov dword ptr,0 ;style
mov dword ptr,WndProc ;lpfnWndProc
mov dword ptr,0 ;cbClsExtra
mov dword ptr,0 ;cbWndExtra
mov edx, ;取实例句柄
mov dword ptr,edx ;hInstance
mov dword ptr,0 ;hIcon
mov dword ptr,0 ;hCursor
mov dword ptr,0 ;hbrBackground
mov dword ptr,0 ;lpszMenuName
lea edx, ;取字符串地址
mov dword ptr,edx ;lpszClassName
call PushStr3 ;将下面的数据地址入栈
db "RegisterClassA",0 ;参数2:要获取的函数名
PushStr3:
push ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov ,eax ;保存RegisterClassA函数地址
lea edx, ;取WNDCLASSA结构体地址
push edx ;参数1:&WNDCLASSA
call eax ;RegisterClassA
call PushStr4 ;将下面的数据地址入栈
db "DefWindowProcA",0 ;参数2:要获取的函数名
PushStr4:
push ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov ,eax ;保存DefWindowProcA函数地址
call PushStr5 ;将下面的数据地址入栈
db "CreateWindowExA",0 ;参数2:要获取的函数名
PushStr5:
push ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov ,eax ;保存CreateWindowExA函数地址
push 0 ;lpParam
push ;hInstance
push 0 ;hMenu
push 0 ;hWndParent
push 200 ;nHeight
push 400 ;nWidth
push 0 ;Y
push 0 ;X
push 10080000h ;dwStyle
push 0 ;lpWindowName
lea edx, ;取字符串地址
push edx ;lpClassName
push 00000010h ;dwExStyle
call eax ;CreateWindowExA
mov ,eax ;保存窗口句柄
call CreateControl ;创建控件
call PushStr6 ;将下面的数据地址入栈
db "GetMessageA",0 ;参数2:要获取的函数名
PushStr6:
push ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov ,eax ;保存GetMessageA函数地址
call PushStr7 ;将下面的数据地址入栈
db "DispatchMessageA",0 ;参数2:要获取的函数名
PushStr7:
push ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov ,eax ;保存DispatchMessageA函数地址
MsgLoop:
call GetGlobal
mov edi,eax
push 0
push 0
push 0
lea edx,
push edx
call dword ptr
lea edx,
push edx
call dword ptr
jmp MsgLoop
;----------------------------------------------------
pop ebp
ret
WndProc:
push ebp
mov ebp,esp
call GetGlobal
mov edi,eax
;------------------------------------------
push
push
push
push
call dword ptr
;------------------------------------------
pop ebp
ret 10h
CreateControl:
call GetGlobal
mov edi,eax
push 0 ;lpParam
push ;hInstance
push 1 ;hMenu
push ;hWndParent
push 20 ;nHeight
push 100 ;nWidth
push 0 ;Y
push 0 ;X
push 50800000h ;dwStyle
push 0 ;lpWindowName
call PushStr10
db "Edit",0 ;lpClassName
PushStr10:
push 0 ;dwExStyle
call dword ptr ;CreateWindowExA
ret
GetGlobal:
mov eax,
and eax,0FFFFF000h
add eax,400h
ret
end main ShellCode
8B 5B 0C 8B 5B 0C 8B 1B 8B 1B 8B 5B 18 8B 43 3C
03 C3 8B 40 78 03 C3 8B 50 20 03 D3 33 C9 8B 34
8A 03 F3 41 0F B6 3E 83 FF 47 75 F2 0F B6 7E 03
83 FF 50 75 E9 0F B6 7E 07 83 FF 41 75 E0 49 8B
50 24 03 D3 0F B7 0C 4A 8B 50 1C 03 D3 8B 34 8A
03 F3 8B FB C3 老铁给力哇{:301_997:} 好好学习下 谢谢分享。。注释得很祥细。。。 很详细 不过具体用的话 还是得像shellcode那样比较精简 说的很明白,谢谢分享 厉害阿 老哥 支持。。。。。 谢谢分享!!
页:
[1]