ASM 板


LINE

看板 ASM  RSS
从来没想过我会学习 machine code, 而且 x86 machine code 实在太复杂, 花了很多心 力才有点进展。本来直接拿起 intel 那令人害怕的手册硬 K, 果然不行, 有看没有懂, 再看 ref 3, 还是看不懂。而在阅读了 ref 1, 2 後, 我如获至宝, 看懂之後再翻阅 ref 3, 终於有了进展。当能看懂时, 心中的兴奋之情, 恐怕只有和我一样在 machine code 里头挣扎的同好才能理解。 不过 x86 machine code 实在太复杂, 我并没能搞懂所有格式。 为什麽要研究 machine code 呢?因为要改写执行档的位址, 做类似 dynamic loader/linker 的事情, 会看这篇文章的朋友, 难道你对於 dynamic loader/linker 的 原理没有兴趣吗?不会想个方法来实验这件事情吗?Binary Hacks--骇客秘传技巧一百招 #72 就在谈这个。 让我们从 intel memory address 开始。intel 着名的 segmentation memory address, 将记忆体位址分为 segment part, offset part, 本文章重点摆在 offset part。而台湾 翻译的基底/索引定址法 (中国的翻译则是 ...) 则为 base/index。 offset part 有三个栏位: base register index register multiplied 1, 2, 4, 8 (1, 2, 4, 8 被称为 scale factor) displacement base + index * scale + displacement = offset part ex: at&t syntax add 0x12345678(%eax, %esi, 4), %esi intel syntax add esi, [eax+esi*4+0x12345678] 本篇文章大量参考 Programming THE 80386 (instruction encoding - p59): ( http://goo.gl/jr50sq ) 这是 1987 年的书 (我写这篇文章的时间是 20130612), 在电脑界这麽快速更新的时代, 照理说应该是过期的书籍, 不过由於相容性的缘故, 里头提到的东西到现在都还是可以用 的, 而且简单不少 (也没有 64 bit mode), intel 手册已经变得又厚又硬难以阅读, 而 这本书讲的比较好理解。有些术语和最新的 intel 手册有些不同, 不过不影响理解。 之前在阅读 IBM 80X86 组合语言实务 ( http://goo.gl/Tmr1Pp )被其复杂的定址模式搞 得我好乱, 现在一次把它搞懂。这些复杂的 address mode 是针对 offset part 而来, 大概就是 base register 和 index register mode 这两种比较复杂。而 16 bit 和 32 bit 又有点不同, 64 bit 没研究, 就不提了。 16 bit 和 32 bit 可用来当 base/index register 的暂存器有些不同。为什麽呢?读懂 machine code 就可以回答这问题。 x86 machine code 顺序, 後面的数字是 byte 数目: prefix 0-4 opcode 1-2 modrm 0-2 displacement 0-4 immediate 0-4 这是这本书的解释, 和目前的 intel 手册有些不同, 目前的 intel 手册把 modrm 分为 modrm + sib, 不过没关系, 原则都是一样的。我建议先看过 ref 1, ref 2 再看这篇, 如果真的没时间至少也要看过 ref 2, 因为他们提到的东西, 我不会特别说明, 请花点时 间看, 若你真想理解这玩意, 应该有觉悟要占去你不少休闲时间。 address_mode.S 1 # practice x86 machine code 2 .code16 3 #.code32 4 .text 5 .global begin 6 begin: 7 add (%bx), %ax 看看 L7 的组语, 这使用了 base register address mode。 objdump -d -m i8086 address_mode.elf 1 descent@w-linux:x86_machine_code$ objdump -d -m i8086 address_mode.elf 2 3 address_mode.elf: file format elf32-i386 4 5 6 Disassembly of section .text: 7 8 00000100 <_text>: 9 100: 03 07 add (%bx),%ax 由於 intel cpu 有 16/32/64 bit mode, 所以我们得选择要让组译器用那种 bit mode 来翻译出 machine code, 这个例子是 16 bit (ref address_mode.S L2, L3)。 03 07 是 machine code, 对应到 opcode modrm 这两栏, 没有 prefix, displacement, immediate 这些部份。 来看看 add 的 opcode: http://css.csail.mit.edu/6.858/2011/readings/i386/ADD.htm ( http://goo.gl/onPA8d ) 有好几个, 看以下这个: 03 /r ADD r16,r/m16 2/6 Add r/m word to word register clock 那栏我看不懂, 有请大大解惑。 所以 03 是 opcode, 03 搞定, 那 07 是什麽? 07 是 modrm 这栏, 再细分解为 2:3:3 栏位, 0000 0111 -> 00 000 111 mod: 00 reg: 000 r/m: 111 把 mod, r/m 拿来查表。 mod = 00 时的对照表 (16 bit) Effective Addressr/m [BX+SI] 000 [BX+DI] 001 [BP+SI] 010 [BP+DI] 011 [SI] 100 [DI] 101 disp16 110 [BX] 111 得到 [BX], 这是 base register address mode reg: 000 代表 ax register register table REGRegister 000EAX/AX 001ECX/CX 010EDX/DX 011EBX/BX 100ESP/SP 101EBP/BP 110ESI/SI 111EDI/DI 得到 add ax, [bx] (intel syntax), 恭喜, 终於看懂 machine code 了。但是要从 add ax, [bx] 得到 03 07 就比较难了。 这在 intel 术语称为: one-byte address mode encoding。 这篇好像有点长了, 不过打铁趁热, 来看看 prefix 的例子。 address_mode1.S 1 # practice x86 machine code 2 .code16 3 #.code32 4 .text 5 .global begin 6 begin: 7 add (%bx), %eax 和 address_mode.S 的差别仅在 %eax, %ax 改成 %eax。我一直被 16 bit 程式码可以使 用 32 bit register 所疑惑, 这样的程式码倒底是 16 bit 还是 32 bit? 当然是 16 bit, 那你和我觉得疑惑可以使用 32 bit register 吗?让我们透过 prefix 解除这疑惑 。 objdump -d -m i8086 address_mode.elf 1 descent@w-linux:x86_machine_code$ objdump -d -m i8086 address_mode.elf 2 3 address_mode.elf: file format elf32-i386 4 5 6 Disassembly of section .text: 7 8 00000100 <_text>: 9 100: 66 03 07 add (%bx),%eax machine code 则多了一个 66, 这就是 prefix, 用来切换 operand size, 这里的例子是 从 16 bit 切换成 32 bit, 本程式执行在 16 bit 下, 而 %eax 是 32 bit operand, 所 以要加上 prefix 0x66, 就这麽简单。 想想看: 什麽是 32 bit 执行环境? A: ... 若在 32 bit 执行环境执行这个 machine code 又是什麽意思? A: .code32 .text .global begin begin: add (%edi), %ax 很有意思吧, x86 就是这麽讨厌又让人喜爱。 好用的组译器:http://radare.org/y/?p=examples&f=rasm ( http://goo.gl/7m3UXy ) 玩 machine code 的朋友一定要试试。 某聚会上我的分享, 就是以这篇为主。 ref: x86/x64 指令幕(适用于 AMD/Intel):http://www.mouseos.com/x64/index.html ( http://goo.gl/D7kzHb ) OpCode:http://www.luocong.com/learningopcode.htm ( http://goo.gl/4fAo5p ) Programming THE 80386 http://ref.x86asm.net/coder32.html ( http://goo.gl/311CF ) // 本文使用 Blog2BBS 自动将Blog文章转成缩址的BBS纯文字 http://goo.gl/TZ4E17 // 原文 blog descent-incoming.blogspot.tw/2013/06/x86-machine-code-0-base-register.html --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 58.114.150.244
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/ASM/M.1399549919.A.C6F.html
1F:推 soheadsome:推 05/08 22:53
2F:推 wgst88w:第二个连结"OpCode"那个网页有木马! 05/09 12:05
http://www.luocong.com/learningopcode/index.htm 这就应该没问题, 是纯 html 网页
3F:推 kingstong:加油给推!只有X86架构才是王道.不需DOSBOX直接DOS就能用 05/09 21:38
4F:推 et84121:推一个 05/10 01:39
※ 编辑: descent (111.184.191.166), 05/10/2014 22:04:00
5F:推 merckhung: Intel 有 release 一个叫 XED2 的东西, 可以帮助解码. 09/24 04:53







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Tech_Job站内搜寻

TOP