首页
社区
课程
招聘
[原创]无PUSH参数,无CALL调用API的一个例子
2010-8-19 20:56 10264

[原创]无PUSH参数,无CALL调用API的一个例子

2010-8-19 20:56
10264
先来看看OD上的样子

00401000   $  55            push    ebp
00401001   .  8BEC          mov     ebp, esp
00401003   .  83C4 E4       add     esp, -1C
00401006   .  B9 07000000   mov     ecx, 7
0040100B   .  33C0          xor     eax, eax
0040100D   .  57            push    edi
0040100E   .  8D7D E4       lea     edi, dword ptr [ebp-1C]
00401011   .  F3:AB         rep     stos dword ptr es:[edi]
00401013   .  5F            pop     edi
00401014   .  C745 E8 00000>mov     dword ptr [ebp-18], 0            ;  (initial cpu selection)
0040101B   .  C745 FC 04000>mov     dword ptr [ebp-4], 4
00401022   .  C745 F4 00304>mov     dword ptr [ebp-C], 00403000      ;  信息框测试!--------123456
00401029   .  C745 F8 1A304>mov     dword ptr [ebp-8], 0040301A      ;  信息框标题!
00401030   .  C745 E4 3D104>mov     dword ptr [ebp-1C], 0040103D
00401037   .  68 64104000   push    <jmp.&kernel32.GetModuleHandleA>
0040103C   .  C3            retn                                     ;  RET 用作跳转到 00401064
0040103D   .  C745 EC 4A104>mov     dword ptr [ebp-14], 0040104A
00401044   .  68 58104000   push    <jmp.&user32.MessageBoxA>
00401049   .  C3            retn
0040104A   .  C9            leave
0040104B   .  C3            retn
0040104C >/$  E8 AFFFFFFF   call    00401000
00401051  |.  6A 00         push    0                                ; /ExitCode = 0
00401053  \.  E8 06000000   call    <jmp.&kernel32.ExitProcess>      ; \ExitProcess
00401058   .- FF25 0C204000 jmp     dword ptr [<&user32.MessageBoxA>>;  user32.MessageBoxA
0040105E   .- FF25 04204000 jmp     dword ptr [<&kernel32.ExitProces>;  kernel32.ExitProcess
00401064   >- FF25 00204000 jmp     dword ptr [<&kernel32.GetModuleH>;  kernel32.GetModuleHandleA




然后看看源码:

		.386
		.model flat, stdcall
		option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include		windows.inc
include		user32.inc
includelib	user32.lib
include		kernel32.inc
includelib	kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
.data
str1	db '信息框测试!--------123456',0
str2	db '信息框标题!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.code
_NewCallAPI proc	;此构造缺点是,你不能随便申请一个与CALL无关的局部变量
local utype,lpcption,lptext,hwnd,MessageBoxret	;申请API局部变量参数要倒着来,返回地址写最后
local lpModuleHandle,GetModuleHandleret
mov	ecx,7;局部变量个数,必需是DD类的
xor	eax,eax
push	edi
lea	edi,GetModuleHandleret
rep	stosd	;初始化局部变量值
pop	edi
mov	lpModuleHandle,0
	mov	utype,MB_YESNO
	mov	lptext,offset str1
	mov	lpcption,offset str2
mov	GetModuleHandleret,$+13
push	GetModuleHandle
retn
mov	MessageBoxret,$+13
push	MessageBox
retn
;push	ExitProcess
;retn
leave
retn
_NewCallAPI endp
start:
invoke _NewCallAPI
invoke	ExitProcess,NULL
end	start

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞6
打赏
分享
最新回复 (19)
雪    币: 654
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
Mx¢Xgt 7 2010-8-19 21:01
2
0
如果要在该函数下申请其他局部变量,申请在API参数变量最前应该也是可以的
雪    币: 247
活跃值: (126)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tianci 2010-8-19 21:36
3
0
标记,学习一下!
雪    币: 120
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sehoooo 2010-8-19 22:51
4
0
比较陈旧的东西了。。avp3.5入口就这么干的。。。。
雪    币: 6071
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2010-8-19 23:16
5
0
5年前写过类似的一个,拿出来改了一下:

masm
 
mycall macro funcname, args:VARARG
    local ofs, retaddr
    sub esp, argcount(args)*4+8
    ofs = 0
    mov dword ptr [esp+ofs], funcname
    ofs = ofs + 4
    mov dword ptr [esp+ofs], retaddr
    ofs = ofs + 4
    for arg, <args>
        mov dword ptr [esp+ofs], repargof(arg)
        ofs = ofs + 4
    endm
    retn
 
retaddr:
endm
start:
    mycall Sleep, 100
    mycall MessageBoxA, 0, "call w/o pushin' arguments", 0, 0
    mycall ExitProcess, 0
end start


ollydbg

00401000 >/$  83EC 0C       sub     esp, 0C
00401003  |.  C70424 701040>mov     dword ptr [esp], <jmp.&kernel32.>
0040100A  |.  C74424 04 1B1>mov     dword ptr [esp+4], mycall.004010>
00401012  |.  C74424 08 640>mov     dword ptr [esp+8], 64
0040101A  \.  C3            retn
0040101B   .  83EC 18       sub     esp, 18
0040101E   .  C70424 761040>mov     dword ptr [esp], <jmp.&user32.Me>
00401025   .  C74424 04 4E1>mov     dword ptr [esp+4], mycall.004010>
0040102D   .  C74424 08 000>mov     dword ptr [esp+8], 0
00401035   .  C74424 0C 003>mov     dword ptr [esp+C], mycall.004030>;  ASCII "call w/o pushin' arguments"
0040103D   .  C74424 10 000>mov     dword ptr [esp+10], 0
00401045   .  C74424 14 000>mov     dword ptr [esp+14], 0
0040104D   .  C3            retn
0040104E   .  83EC 0C       sub     esp, 0C
00401051   .  C70424 6A1040>mov     dword ptr [esp], <jmp.&kernel32.>
00401058   .  C74424 04 691>mov     dword ptr [esp+4], mycall.004010>
00401060   .  C74424 08 000>mov     dword ptr [esp+8], 0
00401068   .  C3            retn
00401069      CC            int3
0040106A   .- FF25 04204000 jmp     [<&kernel32.ExitProcess>]        ;  kernel32.ExitProcess
00401070   .- FF25 00204000 jmp     [<&kernel32.Sleep>]              ;  kernel32.Sleep
00401076   .- FF25 0C204000 jmp     [<&user32.MessageBoxA>]          ;  user32.MessageBoxA
 
雪    币: 517
活跃值: (84)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
triones 6 2010-8-20 09:49
6
0
对付静态逆向,还有点迷惑性。
但骗不过OD,在API头上下断,所有参数照样列举。
动态逆向而言,只是一个小阻碍。

现在编译器开完全优化,那优化后的代码反而更加恶心。
雪    币: 19
活跃值: (1051)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
iceway 2010-8-20 13:05
7
0
能骗过杀软 嘿嘿
雪    币: 654
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
Mx¢Xgt 7 2010-8-20 14:55
8
0
这招太牛了...学习啊可惜俺不懂宏,不知道去哪学?
雪    币: 654
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
Mx¢Xgt 7 2010-8-20 14:57
9
0
想问下..这招是不是已经过时了...而且过时了5年?
雪    币: 393
活跃值: (100)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
iiii 1 2010-8-20 15:27
10
0
没什么过时的说法吧。太单一了。
masm的第一个m指的就是macro 可是那些各种各样的教程却千方百计的阻止别人用macro
fasm的所以汇编指令也可以说其实就是macro 比如你可以自己写个变形后的push代替原来的push。把所有的变形后的指令宏写在同一个头文件中,当要发布软件的时候直接include 这样直接编译出来的就是变形后的代码。 可惜fasm宏里面没有随机数
雪    币: 6071
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2010-8-20 15:37
11
0
用macro写个LCG就行了。
雪    币: 654
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
Mx¢Xgt 7 2010-8-20 15:51
12
0
是啊 ,目前还没看到有汇编书上有教写宏的.....
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nfgfgo 2010-8-20 16:13
13
0
目前gcc编译push参数就是这样的啊
雪    币: 213
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jasonzhou 2010-8-20 16:58
14
0
过时了
雪    币: 16
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
nccgncjt 1 2010-8-21 00:10
15
0
mov  GetModuleHandleret,a123
push  GetModuleHandle
retn
a123:

这样好理解些
雪    币: 16
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
nccgncjt 1 2010-8-21 13:58
16
0
把源码改一下更好理解,红色为更改后的源码内容

.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include                windows.inc
include                user32.inc
includelib        user32.lib
include                kernel32.inc
includelib        kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
.data
str1        db '信息框测试!--------123456',0
str2        db '信息框标题!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
_NewCallAPI        proc          ;此构造缺点是,你不能随便申请一个与CALL无关的局部变量
local        utype,lpcption,lptext,hwnd,MessageBoxret  ;申请API局部变量参数要倒着来,返回地址写最后
local        lpModuleHandle,GetModuleHandleret
mov        ecx,7                ;局部变量个数,必需是DD类的
xor        eax,eax
push        edi
lea        edi,GetModuleHandleret
rep        stosd                  ;初始化局部变量值
pop        edi
mov        lpModuleHandle,0
mov        utype,MB_YESNO
mov        lpcption,offset str2
mov        lptext,offset str1
mov        GetModuleHandleret,a123
push        GetModuleHandle
retn
a123:
mov        eax,eax
mov        MessageBoxret,$+13
push        MessageBox
retn
;push        ExitProcess
;retn
leave
retn
_NewCallAPI        endp
start:
invoke        _NewCallAPI
invoke        ExitProcess,NULL
end        start
雪    币: 5052
活跃值: (2547)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
longloo 2010-8-21 14:34
17
0
mark。。。。。。
雪    币: 22
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
靴子 2010-8-21 14:42
18
0
mark 以后学习下
雪    币: 196
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
邹志勇 2010-10-16 12:11
19
0
实际上是做一个压栈后的堆栈状态~~~~~,直接add esp -n , mov [esp],xxxxxxxx , mov [esp+4],xxxxxxxx........push xxxxxxxx , retn 不是更方便~~
雪    币: 1361
活跃值: (908)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
sssccc 2010-10-16 12:20
20
0
间接的push与间接的call
游客
登录 | 注册 方可回帖
返回