首页
社区
课程
招聘
[求助]只知道函数的地址,如何在程序中调用???
发表于: 2008-5-11 22:59 8906

[求助]只知道函数的地址,如何在程序中调用???

2008-5-11 22:59
8906
问个基础的问题:
只知道程序的地址,如0x77D507EA
     在程序中应该如何调用这个函数呢?
   我用call dword ptr ds:[77D507EAh]的话,编译可以正常通过,但是运行就会出错。如果在里面单步跟踪的话,走到这儿就跳飞了,就像这个例子,一下子跳到0x7c92e460处执行去了。
如我的试验程序temp.asm的代码如下:
.code
start:
call	@lab
@lab:
pop	ebp
lea	ebp,[ebp+6]
jmp	@f
db 'MessBox........',0
@@:
push	0
push	ebp
push	ebp
push	0
call	dword ptr ds:[77d507eah]
ret


反汇编后的代码如下:

00401000 > $  E8 00000000   CALL temp.00401005
00401005   $  5D            POP EBP
00401006   .  8D6D 06       LEA EBP,DWORD PTR SS:[EBP+6]
00401009   .  EB 10         JMP SHORT temp.0040101B
0040100B   .  4D 65 73 73 4>ASCII "MessBox........",0
0040101B   >  6A 00         PUSH 0
0040101D   .  55            PUSH EBP
0040101E   .  55            PUSH EBP
0040101F   .  6A 00         PUSH 0
00401021      FF            DB FF      [COLOR="Red"];此处就是call dword ptr ds:[77d507eah]的机器码了[/COLOR]
00401022      15 EA07D577   ADC EAX,77D507EA    
00401027   .  C3            RETN


而直接用Call MessageBox的话,生成的机器码会有差别
temp2.asm的反汇编的代码如下:
00401000 >/$  E8 00000000   CALL temp2.00401005
00401005  |$  5D            POP EBP
00401006  |.  8D6D 06       LEA EBP,DWORD PTR SS:[EBP+6]
00401009  |.  EB 17         JMP SHORT temp2.00401022
0040100B  |.  4D 65 73 73 4>ASCII "MessBox........."
0040101B  |.  2E 2E 2E 2E 2>ASCII "......",0
00401022  |>  6A 00         PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00401024  |.  55            PUSH EBP                                 ; |Title
00401025  |.  55            PUSH EBP                                 ; |Text
00401026  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
00401028  |.  E8 0B000000   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
0040102D  \.  C3            RETN
0040102E      4D            DB 4D                                    ;  CHAR 'M'
0040102F      61            DB 61                                    ;  CHAR 'a'
00401030      72            DB 72                                    ;  CHAR 'r'
00401031      6B            DB 6B                                    ;  CHAR 'k'
00401032      4C            DB 4C                                    ;  CHAR 'L'
00401033      61            DB 61                                    ;  CHAR 'a'
00401034      62            DB 62                                    ;  CHAR 'b'
00401035      45            DB 45                                    ;  CHAR 'E'
00401036      6E            DB 6E                                    ;  CHAR 'n'
00401037      64            DB 64                                    ;  CHAR 'd'
00401038   $- FF25 00204000 JMP DWORD PTR DS:[<&user32.MessageBoxA>] ;  user32.MessageBoxA   [COLOR="red"] ;注意,此处被编译成了FF25,而前面被编译成了FF15,这有什么差别??[/COLOR]


我查了一下Intel的指令集
FF /2	CALL r/m16	Call near, absolute indirect, address given in r/m16
FF /2	CALL r/m32	Call near, absolute indirect, address given in r/m32
9A cd	CALL ptr16:16	Call far, absolute, address given in operand
9A cp	CALL ptr16:32	Call far, absolute, address given in operand
FF /3	CALL m16:16	Call far, absolute indirect, address given in m16:16
FF /3	CALL m16:32	Call far, absolute indirect, address given in m16:32

那个FF /3还有FF /2是什么意思????
FF15和FF25什么区别????

对了,还有,temp2.exe里面401038处,是跳转指令,跳到402000处,此处是导入表,刚好存储的是MessageBoxA的地址,即0x77d507ea
为什么此处一个jmp,仅仅跳到了402000处,而此处仅是一个双字,它为什么能自动转到0x77d507ea???

谢谢了~

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 1969
活跃值: (46)
能力值: (RANK:550 )
在线值:
发帖
回帖
粉丝
2
FF /3还有FF /2具体什么意思我也不清楚
FF15 00104000 call dword ptr [401000]
FF25 00104000 jmp dword ptr [401000]
FF15是call 而FF25是jmp指令 call指令有返回 而jmp指令没有

我用call dword ptr ds:[77D507EAh]的话,编译可以正常通过,但是运行就会出错。如果在里面单步跟踪的话,走到这儿就跳飞了,就像这个例子,一下子跳到0x7c92e460处执行去了。

如果你想调用0x77D507EA地址处的函数 应该是call 77D507EAh 而不是call [77D507EAh] 在你这里77D507EAh地址处的数据应该是0x7c92e460 所以call [77D507EAh] 就相当于 call 7c92e460h了

最后一个问题的原因同样如此 请您再理解一下 address与[address]的区别
2008-5-12 09:24
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
[QUOTE=hawking;452556]FF /3还有FF /2具体什么意思我也不清楚
FF15 00104000 call dword ptr [401000]
FF25 00104000 jmp dword ptr [401000]
FF15是call 而FF25是jmp指令 call指令有返回 而jmp指令没有

我用call d...[/QUOTE]

恩,谢谢
我将程序改成这样的了
.data
_proc	dd	77d507eah

.code
start:
call	@lab
@lab:
pop	ebp
lea	ebp,[ebp+6]
jmp	@f
db 'MessBox...............',0
@@:
push	0
push	ebp
push	ebp
push	0
call	_proc
ret

还是编译通过,但是单步到call _proc之后,就会弹出一个错误的对话框
说77d507eah地址处不可读……

我稍微改变了一下代码:
.data
_proc	dd	77d507eah

.code
start:
call	@lab
@lab:
pop	ebp
lea	ebp,[ebp+6]
jmp	@f
db 'MessBox...............',0
@@:
push	0
push	ebp
push	ebp
push	0
call	@f
@@:
pop	ebp
add	ebp,0Bh
push	ebp
jmp          _proc
ret

这样编译后,代码微微有些不同
就是前面那个是FF15 ***
后面这段代码是FF25 ***
但后面这段代码同样提示77d507ea不可读…………

这是怎么回事呢???

还有一个问题:
call MessageBox
编译成了:
00401028  |.  E8 0B000000   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
即跳到了:
00401038   $- FF25 00204000 JMP DWORD PTR DS:[<&user32.MessageBoxA>] ;  user32
而402000处是导入表,存放着77d507ea,它仅是一个双字
为什么从401038处jmp到402000,就能直接转到77d507ea处执行呢???

没法理解这是为什么……

3Q
2008-5-12 10:40
0
雪    币: 1969
活跃值: (46)
能力值: (RANK:550 )
在线值:
发帖
回帖
粉丝
4
1 77d507ea应该是某个系统user32.DLL的空间 如果你没有加载该DLL而直接call当然会不可读
2 [402000] = 77d507ea
jmp [402000] = jmp 77d507ea = jmp messageboxa
2008-5-12 12:08
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
[QUOTE=hawking;452633]1 77d507ea应该是某个系统user32.DLL的空间 如果你没有加载该DLL而直接call当然会不可读
2 [402000] = 77d507ea
jmp [402000] = jmp 77d507ea = jmp messageboxa[/QUOTE]

恩,谢谢,明白了

但是我用如下的代码调用仍然有问题:
.data

_proc	dd	77d507eah

.code
start:
call	@lab
@lab:
pop	ebp
lea	ebp,[ebp+6]
jmp	@f
db 'MessBox...............',0
@@:
push	0
push	ebp
push	ebp
push	0

call	dword ptr [_proc]
ret


并且我已经用了include user32.inc和include user32.lib了

反汇编后的代码为:
00401000 >/$  E8 00000000                             CALL temp2.00401005
00401005  |$  5D                                      POP EBP
00401006  |.  8D6D 06                                 LEA EBP,DWORD PTR SS:[EBP+6]
00401009  |.  EB 17                                   JMP SHORT temp2.00401022
0040100B  |.  4D 65 73 73 42 6F 78 2E 2E 2E 2E 2E 2E >ASCII "MessBox........."
0040101B  |.  2E 2E 2E 2E 2E 2E 00                    ASCII "......",0
00401022  |>  6A 00                                   PUSH 0
00401024  |.  55                                      PUSH EBP
00401025  |.  55                                      PUSH EBP
00401026  |.  6A 00                                   PUSH 0
00401028  |.  FF15 00204000                           CALL DWORD PTR DS:[402000]
0040102E  \.  C3                                      RETN


而在程序里面直接用call MessageBox来调用的话,则产生的反汇编代码如下:
00401000 >/$  E8 00000000   CALL temp3.00401005
00401005  |$  5D            POP EBP
00401006  |.  8D6D 06       LEA EBP,DWORD PTR SS:[EBP+6]
00401009  |.  EB 17         JMP SHORT temp3.00401022
0040100B  |.  4D 65 73 73 4>ASCII "MessBox........."
0040101B  |.  2E 2E 2E 2E 2>ASCII "......",0
00401022  |>  6A 00         PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00401024  |.  55            PUSH EBP                                 ; |Title
00401025  |.  55            PUSH EBP                                 ; |Text
00401026  |.  6A 00         PUSH 0                                   ; |hOwner = NULL
00401028  |.  E8 0B000000   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
0040102D  \.  C3            RETN
0040102E      4D            DB 4D                                    ;  CHAR 'M'
0040102F      61            DB 61                                    ;  CHAR 'a'
00401030      72            DB 72                                    ;  CHAR 'r'
00401031      6B            DB 6B                                    ;  CHAR 'k'
00401032      4C            DB 4C                                    ;  CHAR 'L'
00401033      61            DB 61                                    ;  CHAR 'a'
00401034      62            DB 62                                    ;  CHAR 'b'
00401035      45            DB 45                                    ;  CHAR 'E'
00401036      6E            DB 6E                                    ;  CHAR 'n'
00401037      64            DB 64                                    ;  CHAR 'd'
00401038   $- FF25 00204000 JMP DWORD PTR DS:[<&user32.MessageBoxA>] ;  user32.MessageBoxA


好像差别就是:
在调用的时候:
第一个程序是:
00401028  |.  FF15 00204000                           CALL DWORD PTR DS:[402000]
然后402000处放着0x77d507ea

而正常的那个程序是:
00401028  |.  E8 0B000000   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
00401038   $- FF25 00204000 JMP DWORD PTR DS:[<&user32.MessageBoxA>] ;  user32.MessageBoxA
也就是用了一个call,到一条jmp远跳转指令,再跳到0x77d507ea

所以我也试着直接改成用jmp跳到0x77d507ea,而不用call指令
所以代码改成下面这样的了:
.data

_proc	dd	77d507eah

.code
start:
call	@lab
@lab:
pop	ebp
lea	ebp,[ebp+6]
jmp	@f
db 'MessBox...............',0
@@:
push	0
push	ebp
push	ebp
push	0
call	@f
@@:
pop	ebp
add	ebp,0Bh
push	ebp
jmp	dword ptr [_proc]
ret


但是,错误都与原来一样的~~~~

这是为什么???

3Q
2008-5-13 19:21
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
6
楼主还是没有理解2楼和4楼的意思。

1. 并不是说include了user32.inc和user32.lib,编译后的程序运行时就会加载user32.dll的。

像你楼上这样写法,如果程序(除了include语句之外)只有这样的话,输入表中根本没有user32.dll的函数(同样也没有kernel32.dll的函数)。
在这种情况下,你的程序运行时,其实只加载了ntdll.dll,user32.dll根本没加载。

2. 是call _proc或jmp _proc,而不是call dword ptr [_proc]或jmp dword ptr [_proc]

还有,只是为了演示call一个地址,用得着用那么多自定位的代码吗……

像下面这样,就可以调用成功并且正常退出(启动时没加载user32.dll,可以自己LoadLibrary加载)
.386 
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib 

.const
_proc dd 77D5058Ah          ;我电脑中的MessageBoxA地址
lpCaption db 'Message',0
lpdllname db 'user32.dll',0

.code
start:
invoke LoadLibrary, addr lpdllname
push eax
push 0
push offset lpcaption
push offset lpCaption
push 0
call _proc
call FreeLibrary
invoke ExitProcess, NULL
end start
2008-5-14 19:49
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
学习了。。。。
2008-5-22 18:10
0
游客
登录 | 注册 方可回帖
返回
//