注册 登录
编程论坛 汇编论坛

如何计算上面程序的返回地址?

vfdff 发布于 2008-10-12 23:47, 3394 次点击
;msgbx.asm file.
.386p
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

.code

start:
    push MB_ICONINFORMATION or MB_OK
    call Func1
    db "Test",0
Func1:
    call Func2
    db "Hello",0
Func2:
    push NULL   
    call MessageBoxA
;    ret
end start
如何计算上面程序的返回地址
我使用 masm32 编译后得到的 msgbx.obj 中查看到的返回地址是 0x0a000000(返回地址.JPG)
但是对masm32 编译后得到的 msgbx.exe 反汇编后得到地址却是 0x00402000(返回地址1.JPG)
为什么不一样?
12 回复
#2
ONEPROBLEM2008-10-13 09:35
LZ,是不是我太菜了,我看不懂啊~~
在"返回地址.JPG"这个图片中的"0x0a000000",到底是"0x000000a0"还是"0x0a000000"啊?
还有,这两个文件好像是不一样的,obj是目标文件,面exe是可执行文件,已经链接过了,会不会多了什么东西?
再说了,上图好像是"线性地址",下图是相对于文件头的"偏移地址",是不是不一样啊?
#3
zklhp2008-10-13 12:46
[bo][un]ONEPROBLEM[/un] 在 2008-10-13 09:35 的发言:[/bo]

LZ,是不是我太菜了,我看不懂啊~~
在"返回地址.JPG"这个图片中的"0x0a000000",到底是"0x000000a0"还是"0x0a000000"啊?
还有,这两个文件好像是不一样的,obj是目标文件,面exe是可执行文件,已经链接过了,会不会 ...


偶也感觉有点乱……
#4
你们都要疼我哦2008-10-13 18:10
磁盘文件上的地址和虚拟地址是不同的.
问题也很模糊不清.

楼主如果有志于软件安全 代码调试 分析 等等这方面的学习,还是要系统的从基础的汇编学起 在了解PE格式的基础上,学习反汇编和一些基本的动态 静态 调试方法.
#5
vfdff2008-10-14 00:20
回复 2# ONEPROBLEM 的帖子
0x0a000000 呀
intel 的机子使用的是little endian 排序,所以我们看到的好像是 0x0a000000
#6
你们都要疼我哦2008-10-14 01:05
[bo][un]vfdff[/un] 在 2008-10-14 00:20 的发言:[/bo]

0x0a000000 呀
intel 的机子使用的是little endian 排序,所以我们看到的好像是 0x0a000000


这是错误的.

用查看器打开的磁盘文件,看到的是磁盘文件的地址,地址就是地址,看到什么就是什么,
地址里面的数据才是需要注意顺序的.
#7
vfdff2008-10-15 00:49
http://www.chinaunix.net/jh/23/823662.html
little endian和big endian是表示计算机字节顺序的两种格式,所谓的字节顺序指的是长度跨越多个字节的数据的存放形式.
        假设从地址0x00000000开始的一个字中保存有数据0x1234abcd,那么在两种不同的内存顺序的机器上从字节的角度去看的话分别表示为:
       1)little endian:在内存中的存放顺序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12
       2)big  endian:在内存中的存放顺序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd
       需要特别说明的是,以上假设机器是每个内存单元以8位即一个字节为单位的.
       简单的说,ittle endian把低字节存放在内存的低位;而big endian将低字节存放在内存的高位.
       现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系列的CPU采用的是big endian.
#8
你们都要疼我哦2008-10-15 03:58
磁盘上的文件的地址我们一般叫File Offset,有时候也随便称为磁盘物理偏移地址, 用任何查看器打开看,都是从0开始.要注意这是地址,而不是内容. 内容里的地址或其他数据,要按照规则大端或小端去理解.0x000000a0就是磁盘物理偏移地址,不需要你自己去错误的想象成是0x0a000000. 如果地址作为数据存在,那是需要注意大小端顺序. 稍微有点抽象,但是不难理解. 另外还要注意,你上面贴的那段内容包括原贴的一些回贴,都很不严谨甚至有错误.

这些知识是软件调试方面的入门基础知识.

另外很多东西是没法放在一起比较的,比如OBJ和EXE去比较异同.没什么意义.

有个小小的建议,就是最好能系统学习汇编, 看书要看经典的.
偏底层的学习,汇编是必须精通的.
推荐
罗云彬的汇编书
C++的随便了
罗云彬翻译的 KmdTutCn 讲汇编写驱动的
windows核心编程 5版
加密解密3
ROOTKIT-WINDOWS内核防护
楚狂人的 天书夜读 ,电子版有, 马上也会出书了

综合你的帖子和问题,上面这些书可能适合你,也全都是经典.
不要看一些拼凑书,张争秋那本就是.
#9
zklhp2008-10-15 12:36
[bo][un]你们都要疼我哦[/un] 在 2008-10-15 03:58 的发言:[/bo]

磁盘上的文件的地址我们一般叫File Offset,有时候也随便称为磁盘物理偏移地址, 用任何查看器打开看,都是从0开始.要注意这是地址,而不是内容. 内容里的地址或其他数据,要按照规则大端或小端去理解.0x000000a0就是磁盘 ...


同意!!!
#10
cnhanxiao2008-10-17 08:57
未经连接,哪来地址?

关于高址结尾结尾还是低址结尾,Intel采用后者。体验:

            程序中,用堆栈来构造结构的方法[原创]

一个结构:

S struct
  SSize db 01
  Rsed db 02
  Count dw 0304h
  BufAddr dd 05060708h
  Num dq 090A0B0C0D0E0F10h
S ends

我们来看一下上面的结构其数据在内存中的实际情况,请大家体会,80X86的低址低字节结尾:

  eds:xxxxxxxx:01 02 04 03 08 07 06 05 10 0F 0E 0D 0C 0B 0A 09 ;Hex进制

假如我们使用堆栈来构造这个结构,应该如何做呢?

我们使用16位和32位混合压栈的方式,来构造一个结构。为了清晰,我们使用寄存器压栈,不使用立即数压栈。

假设:堆栈指针ESP=00000000h,EDS=ESS——注意,这很重要,不过保护模式下FLAT模式,是自然相等的。

 ;构造Num
 mov eax,090A0B0Ch
 push eax  ;执行完,ESP=FFFFFFFCh
 mov eax,0D0E0F10h
 push eax  ;执行完,ESP=FFFFFFF8h
 ;构造BufAddr
 mov eax,05060708h
 push eax  ;执行完,ESP=FFFFFFF4h
 ;构造Count
 mov ax,0304h
 push ax  ;执行完,ESP=FFFFFFF2h
 ;构造Rsed和SSize,注意低址低字节
 mov ax,0201h
 push ax  ;执行完,ESP=FFFFFFF0h
 ;
 mov esi,esp  ;用当前ESP装填ESI,很关键,想想为什么:)
 lea    esp,[esi+16]  ;猜猜这句?呵呵——新加,不过要注意?

现在,我们来看这段程序执行完毕后,内存中ESI起始的16字节的内容:

  eds:FFFFFFF0:01 02 04 03 08 07 06 05 10 0F 0E 0D 0C 0B 0A 09 ;Hex进制

是不是已经通过堆栈构造了一个数据结构了?

这就是堆栈巧妙使用技术之一,其实呢,WIN32 API都是利用堆栈传递参数,这里只是让大家清晰80X86的低址低字节。

新加的一句是释放掉所构造的数据包,所以一定在数据包使用完毕之前,不要执行此句,否则一旦有指令压栈,数据包就被破坏了。

编程论坛 汇编语言专区 cnhanxiao [转载请保留]

[[it] 本帖最后由 cnhanxiao 于 2008-10-17 09:01 编辑 [/it]]
#11
珍珍2008-10-20 15:22
#12
vfdff2008-11-01 13:43
我一直没有明白,为什么这 返回地址.jpg  引起这么多争议
刚才猛然才发现这个图有点不好,就是它刚显示了两个很接近的地址,我感觉有可能上面的讨论 就是由于这点没有清楚才导致的
红色方框中的地址当然就是真正的地址,也就是0x000000a0h 不会由争议
但是我其实说的是黄色方框中的地址,这个地址我个人感觉是 0x0a000000h
不好意思了,是我没有说清楚,因为我一直没有注意到 红色方框中的地址
#13
cnhanxiao2008-11-01 17:22
回复 12# 的帖子
编译得到目标文件,连接产生可执行文件。
目标文件不会有正确的地址。
而可执行文件,就有正确的相对地址了(根据文件头参数生成)。
你这样试试吧,去掉扩展名exe再看看。

光听你说返回地址了,你的程序问题多多啊:)
你想显示一个消息框,非要复杂地调用子程序,可子程序都没返回,只是其一。其二,利用堆栈为MessageBox函数传递参数,不说参数不够,最重要的是堆栈早被你的子程序调用破坏了。你自己观察一下堆栈变化吧。

[[it] 本帖最后由 cnhanxiao 于 2008-11-1 17:45 编辑 [/it]]
1