精华内容
下载资源
问答
  • 2022-04-12 09:45:18

    反汇编过程:

    1.确定需要反汇编代码区域。

    2.读取该代码区域所包含的值,并执行一次查表操作,将其机器码与其汇编语言助机符对应起来。

    3.对其汇编语言等价形式进行格式化(两种主要格式:x86汇编语法:AT&T和Intel_What’smean的博客-CSDN博客),并将其在反汇编代码中输出。

    线性扫描反汇编

    反汇编指令位置确定:一条指令结束、另一条指令开始的地方。

    反汇编从一个代码段的第一个字节开始,以线性模式扫描整个代码段,逐条反汇编每条指令,直到完成整个代码段。

    优点:能够完全覆盖程序的所有代码段。

    缺点:没有考虑到代码中可能混有数据。

    GNU 调试器(gdb)、微软公司的 WinDbg 调试器和 objdump 实用工具的反汇编引擎均采用线
    性扫描算法。

    递归下降反汇编

    递归下降反汇编强调控制流的概念。根据一条指令是否被另一条指令引用来决定是否进行反汇编。

    1. 顺序流指令
            顺序流指令将执行权传递给紧随其后的下一条指令。顺序流指令的例子包括简单算术指令,
    如 add;寄存器与内存之间的传输指令,如 mov;栈操作指令,如 push 和 pop。这些指令的反汇
    编过程以线性扫描方式进行。
    2. 条件分支指令
            条件分支指令(如 x86 jnz)提供两条可能的执行路径。如果条件为真,则执行分支,并且
    必须修改指令指针,使其指向分支的目标。但是,如果条件为假,则继续以线性模式执行指令,
    并使用线性扫描方法反汇编下一条指令。因为不可能在静态环境中确定条件测试的结果,递归下
    降算法会反汇编上述两条路径。同时,它将分支目标指令的地址添加到稍后才进行反汇编的地址
    列表中,从而推迟分支目标指令的反汇编过程。
    3. 无条件分支指令
            无条件分支并不遵循线性流模式,因此,它由递归下降算法以不同的方式处理。与顺序流指
    令一样,执行权只能传递给一条指令,但那条指令不需要紧接在分支指令后面。
            递归下降反汇编器将尝试确定无条件跳转的目标,并将目标地址添加到要反汇编的地址列表中。但某些无条件分支可能会给递归下降反汇编器造成麻烦。如果跳转指令的目标取决于一个运行时值,这时使用静态分析就无法确定跳转目标。x86 的 jmp eax 指令就证实了这个问题。只有程序确实正在运行时,eax 寄存器中才会包含一个值(通常call后函数返回值保存在eax中)。由于寄存器在静态分析过程中不包含任何值,因此无法确定跳转指令的目标,也就无法确定该从什么地方继续反汇编过程。

    4. 函数调用指令
            函数调用指令的运行方式与无条件跳转指令非常相似(包括反汇编器无法确定 call eax 等指
    令的目标),唯一的不同在于,一旦函数完成,执行权将返回给紧跟在调用指令后面的指令。在这
    方面,它们与条件分支指令类似,因为它们都生成两条执行路径。调用指令的目标地址被添加到推
    迟进行反汇编的地址列表中,而紧跟在调用后面的指令则以类似于线性扫描的方式进行反汇编。
    从被调用函数返回时,如果程序的运行出现异常,递归下降就有可能失败。例如,函数中的
    代码可能会有意窜改该函数的返回地址,这样,在函数完成时,控制权将返回到一个反汇编器无
    法预知的地址。

    5. 返回指令
            有时,递归下降算法访问了所有的路径。而且,函数返回指令(如 x86 ret)没有提供接下
    来将要执行的指令的信息。这时,如果程序确实正在运行,则可以从运行时栈顶部获得一个地址,
    并从这个地址开始恢复执行指令。但是,反汇编器并不具备访问栈的能力,因此反汇编过程会突
    然终止。这时,递归下降反汇编器会转而处理前面搁置在一旁的延迟反汇编地址列表。反汇编器
    从这个列表中取出一个地址,并从这个地址开始继续反汇编过程。递归下降反汇编算法正是因此
    而得名。


    优点:它具有区分代码与数据的强大能力。作为一种基于控制流的算法,它很少会在反汇编过程中错误地将数据值作为代码处理。

    缺点:它无法处理间接代码路径,如利用指针表来查找目标地址的跳转或调用。然而,通过采用一
    些用于识别指向代码的指针的启发(heuristics)式方法,递归下降反汇编器能够提供所有代码,
    并清楚地区分代码与数据。

    更多相关内容
  • 反汇编指令与机器码对照表,按字母排序,有索引,有对应的英文解释,非常方便,可以用360极速浏览器打开
  • java反汇编指令.doc

    2020-06-04 15:45:09
    java反汇编指令
  • 反汇编指令与机器码对照表

    热门讨论 2011-07-20 22:02:33
    反汇编指令与机器码对照表,按字母排序,有索引,非常方便
  • hsdis-i386.dll用于java二进制文件反汇编,一般结合jitwatch用于查看底层代码的指令重排序,分析多线程中的可见性问题。
  • 电脑32位反汇编指令大全,用于电脑反汇编后的代码读取
  • keil调试教程、反汇编技巧经验、ARM汇编指令
  • 改进了以前的反汇编的错误,增加了地址标签输出
  • 易语言反汇编模块

    2020-07-18 03:41:25
    易语言反汇编模块源码,反汇编模块,测试,十六进制字节文本组初使,字节集到十六进制文本,字节到十六进制文本,十六进制文本到字节集,数值文本到字节集,调整字节集长度,调整文本长度_增加,整理文本_16进制,插入文本,初使...
  •  objdump命令参考:https://blog.csdn.net/zoomdy/article/details/50563680 本文以最简单的程序开始,剖析反汇编之后的程序最小执行系统以及初始化、判断语句、循环语句以及函数及其调用过程在反汇编指令集中的...

            因近期工作需要,需要利用objdump工具剖析程序指定可执行程序,以检查错误函数(语句)。

            objdump命令参考:https://blog.csdn.net/zoomdy/article/details/50563680


            本文以最简单的程序开始,剖析反汇编之后的程序最小执行系统以及初始化、判断语句、循环语句以及函数及其调用过程在反汇编指令集中的形式,方便在工作过程中的异常程序中寻找异常地址。

            文件组成:

            最简文件组成:main.c Makefile

            Makefile代码:

    TRGET = main.out
    
    all: clean $(TRGET)
    
    $(TRGET):main.o
    	cc main.o -o $(TRGET) 
    main.o:
    
    clean:
    	rm -f *.o;rm -f *.out
    
    

            编辑方式:以挂载的方式挂载到linux系统上,编辑在Window上的NotePad++

            从最简程序开始:(这是我能想到最简单的程序了)

    #include <stdio.h>
    
    int main()
    {
    	return 0;
    }

            反汇编指令:

            objdump -C -S main.out > objdump_main_00.txt

            反汇编结果:

    main.out:     file format elf32-i386
    
    Disassembly of section .init:
    
    08048254 <_init>:
     8048254:	55                   	push   %ebp
     8048255:	89 e5                	mov    %esp,%ebp
     8048257:	83 ec 08             	sub    $0x8,%esp
     804825a:	e8 51 00 00 00       	call   80482b0 <call_gmon_start>
     804825f:	e8 a4 00 00 00       	call   8048308 <frame_dummy>
     8048264:	e8 87 01 00 00       	call   80483f0 <__do_global_ctors_aux>
     8048269:	c9                   	leave  
     804826a:	c3                   	ret    
    Disassembly of section .plt:
    
    0804826c <__libc_start_main@plt-0x10>:
     804826c:	ff 35 20 95 04 08    	pushl  0x8049520
     8048272:	ff 25 24 95 04 08    	jmp    *0x8049524
     8048278:	00 00                	add    %al,(%eax)
    	...
    
    0804827c <__libc_start_main@plt>:
     804827c:	ff 25 28 95 04 08    	jmp    *0x8049528
     8048282:	68 00 00 00 00       	push   $0x0
     8048287:	e9 e0 ff ff ff       	jmp    804826c <_init+0x18>
    Disassembly of section .text:
    
    0804828c <_start>:
     804828c:	31 ed                	xor    %ebp,%ebp
     804828e:	5e                   	pop    %esi
     804828f:	89 e1                	mov    %esp,%ecx
     8048291:	83 e4 f0             	and    $0xfffffff0,%esp
     8048294:	50                   	push   %eax
     8048295:	54                   	push   %esp
     8048296:	52                   	push   %edx
     8048297:	68 ac 83 04 08       	push   $0x80483ac
     804829c:	68 58 83 04 08       	push   $0x8048358
     80482a1:	51                   	push   %ecx
     80482a2:	56                   	push   %esi
     80482a3:	68 34 83 04 08       	push   $0x8048334
     80482a8:	e8 cf ff ff ff       	call   804827c <__libc_start_main@plt>
     80482ad:	f4                   	hlt    
     80482ae:	90                   	nop    
     80482af:	90                   	nop    
    
    080482b0 <call_gmon_start>:
     80482b0:	55                   	push   %ebp
     80482b1:	89 e5                	mov    %esp,%ebp
     80482b3:	53                   	push   %ebx
     80482b4:	e8 00 00 00 00       	call   80482b9 <call_gmon_start+0x9>
     80482b9:	5b                   	pop    %ebx
     80482ba:	81 c3 63 12 00 00    	add    $0x1263,%ebx
     80482c0:	52                   	push   %edx
     80482c1:	8b 83 fc ff ff ff    	mov    0xfffffffc(%ebx),%eax
     80482c7:	85 c0                	test   %eax,%eax
     80482c9:	74 02                	je     80482cd <call_gmon_start+0x1d>
     80482cb:	ff d0                	call   *%eax
     80482cd:	58                   	pop    %eax
     80482ce:	5b                   	pop    %ebx
     80482cf:	c9                   	leave  
     80482d0:	c3                   	ret    
     80482d1:	90                   	nop    
     80482d2:	90                   	nop    
     80482d3:	90                   	nop    
    
    080482d4 <__do_global_dtors_aux>:
     80482d4:	55                   	push   %ebp
     80482d5:	89 e5                	mov    %esp,%ebp
     80482d7:	83 ec 08             	sub    $0x8,%esp
     80482da:	80 3d 38 95 04 08 00 	cmpb   $0x0,0x8049538
     80482e1:	74 0f                	je     80482f2 <__do_global_dtors_aux+0x1e>
     80482e3:	eb 1f                	jmp    8048304 <__do_global_dtors_aux+0x30>
     80482e5:	8d 76 00             	lea    0x0(%esi),%esi
     80482e8:	83 c0 04             	add    $0x4,%eax
     80482eb:	a3 34 95 04 08       	mov    %eax,0x8049534
     80482f0:	ff d2                	call   *%edx
     80482f2:	a1 34 95 04 08       	mov    0x8049534,%eax
     80482f7:	8b 10                	mov    (%eax),%edx
     80482f9:	85 d2                	test   %edx,%edx
     80482fb:	75 eb                	jne    80482e8 <__do_global_dtors_aux+0x14>
     80482fd:	c6 05 38 95 04 08 01 	movb   $0x1,0x8049538
     8048304:	c9                   	leave  
     8048305:	c3                   	ret    
     8048306:	89 f6                	mov    %esi,%esi
    
    08048308 <frame_dummy>:
     8048308:	55                   	push   %ebp
     8048309:	89 e5                	mov    %esp,%ebp
     804830b:	83 ec 08             	sub    $0x8,%esp
     804830e:	a1 4c 94 04 08       	mov    0x804944c,%eax
     8048313:	85 c0                	test   %eax,%eax
     8048315:	74 19                	je     8048330 <frame_dummy+0x28>
     8048317:	b8 00 00 00 00       	mov    $0x0,%eax
     804831c:	85 c0                	test   %eax,%eax
     804831e:	74 10                	je     8048330 <frame_dummy+0x28>
     8048320:	83 ec 0c             	sub    $0xc,%esp
     8048323:	68 4c 94 04 08       	push   $0x804944c
     8048328:	ff d0                	call   *%eax
     804832a:	83 c4 10             	add    $0x10,%esp
     804832d:	8d 76 00             	lea    0x0(%esi),%esi
     8048330:	c9                   	leave  
     8048331:	c3                   	ret    
     8048332:	90                   	nop    
     8048333:	90                   	nop    
    
    08048334 <main>:
     8048334:	55                   	push   %ebp
     8048335:	89 e5                	mov    %esp,%ebp
     8048337:	83 ec 08             	sub    $0x8,%esp
     804833a:	83 e4 f0             	and    $0xfffffff0,%esp
     804833d:	b8 00 00 00 00       	mov    $0x0,%eax
     8048342:	83 c0 0f             	add    $0xf,%eax
     8048345:	83 c0 0f             	add    $0xf,%eax
     8048348:	c1 e8 04             	shr    $0x4,%eax
     804834b:	c1 e0 04             	shl    $0x4,%eax
     804834e:	29 c4                	sub    %eax,%esp
     8048350:	b8 00 00 00 00       	mov    $0x0,%eax
     8048355:	c9                   	leave  
     8048356:	c3                   	ret    
     8048357:	90                   	nop    
    
    08048358 <__libc_csu_init>:
     8048358:	55                   	push   %ebp
     8048359:	89 e5                	mov    %esp,%ebp
     804835b:	57                   	push   %edi
     804835c:	56                   	push   %esi
     804835d:	53                   	push   %ebx
     804835e:	83 ec 0c             	sub    $0xc,%esp
     8048361:	e8 00 00 00 00       	call   8048366 <__libc_csu_init+0xe>
     8048366:	5b                   	pop    %ebx
     8048367:	81 c3 b6 11 00 00    	add    $0x11b6,%ebx
     804836d:	e8 e2 fe ff ff       	call   8048254 <_init>
     8048372:	8d 83 20 ff ff ff    	lea    0xffffff20(%ebx),%eax
     8048378:	8d 93 20 ff ff ff    	lea    0xffffff20(%ebx),%edx
     804837e:	89 45 f0             	mov    %eax,0xfffffff0(%ebp)
     8048381:	29 d0                	sub    %edx,%eax
     8048383:	31 f6                	xor    %esi,%esi
     8048385:	c1 f8 02             	sar    $0x2,%eax
     8048388:	39 c6                	cmp    %eax,%esi
     804838a:	73 16                	jae    80483a2 <__libc_csu_init+0x4a>
     804838c:	89 d7                	mov    %edx,%edi
     804838e:	89 f6                	mov    %esi,%esi
     8048390:	ff 14 b2             	call   *(%edx,%esi,4)
     8048393:	8b 4d f0             	mov    0xfffffff0(%ebp),%ecx
     8048396:	29 f9                	sub    %edi,%ecx
     8048398:	46                   	inc    %esi
     8048399:	c1 f9 02             	sar    $0x2,%ecx
     804839c:	39 ce                	cmp    %ecx,%esi
     804839e:	89 fa                	mov    %edi,%edx
     80483a0:	72 ee                	jb     8048390 <__libc_csu_init+0x38>
     80483a2:	83 c4 0c             	add    $0xc,%esp
     80483a5:	5b                   	pop    %ebx
     80483a6:	5e                   	pop    %esi
     80483a7:	5f                   	pop    %edi
     80483a8:	c9                   	leave  
     80483a9:	c3                   	ret    
     80483aa:	89 f6                	mov    %esi,%esi
    
    080483ac <__libc_csu_fini>:
     80483ac:	55                   	push   %ebp
     80483ad:	89 e5                	mov    %esp,%ebp
     80483af:	57                   	push   %edi
     80483b0:	56                   	push   %esi
     80483b1:	53                   	push   %ebx
     80483b2:	e8 00 00 00 00       	call   80483b7 <__libc_csu_fini+0xb>
     80483b7:	5b                   	pop    %ebx
     80483b8:	81 c3 65 11 00 00    	add    $0x1165,%ebx
     80483be:	8d 83 20 ff ff ff    	lea    0xffffff20(%ebx),%eax
     80483c4:	8d bb 20 ff ff ff    	lea    0xffffff20(%ebx),%edi
     80483ca:	29 f8                	sub    %edi,%eax
     80483cc:	c1 f8 02             	sar    $0x2,%eax
     80483cf:	83 ec 0c             	sub    $0xc,%esp
     80483d2:	8d 70 ff             	lea    0xffffffff(%eax),%esi
     80483d5:	eb 05                	jmp    80483dc <__libc_csu_fini+0x30>
     80483d7:	90                   	nop    
     80483d8:	ff 14 b7             	call   *(%edi,%esi,4)
     80483db:	4e                   	dec    %esi
     80483dc:	83 fe ff             	cmp    $0xffffffff,%esi
     80483df:	75 f7                	jne    80483d8 <__libc_csu_fini+0x2c>
     80483e1:	e8 2e 00 00 00       	call   8048414 <_fini>
     80483e6:	83 c4 0c             	add    $0xc,%esp
     80483e9:	5b                   	pop    %ebx
     80483ea:	5e                   	pop    %esi
     80483eb:	5f                   	pop    %edi
     80483ec:	c9                   	leave  
     80483ed:	c3                   	ret    
     80483ee:	90                   	nop    
     80483ef:	90                   	nop    
    
    080483f0 <__do_global_ctors_aux>:
     80483f0:	55                   	push   %ebp
     80483f1:	89 e5                	mov    %esp,%ebp
     80483f3:	53                   	push   %ebx
     80483f4:	52                   	push   %edx
     80483f5:	bb 3c 94 04 08       	mov    $0x804943c,%ebx
     80483fa:	a1 3c 94 04 08       	mov    0x804943c,%eax
     80483ff:	eb 0a                	jmp    804840b <__do_global_ctors_aux+0x1b>
     8048401:	8d 76 00             	lea    0x0(%esi),%esi
     8048404:	83 eb 04             	sub    $0x4,%ebx
     8048407:	ff d0                	call   *%eax
     8048409:	8b 03                	mov    (%ebx),%eax
     804840b:	83 f8 ff             	cmp    $0xffffffff,%eax
     804840e:	75 f4                	jne    8048404 <__do_global_ctors_aux+0x14>
     8048410:	58                   	pop    %eax
     8048411:	5b                   	pop    %ebx
     8048412:	c9                   	leave  
     8048413:	c3                   	ret    
    Disassembly of section .fini:
    
    08048414 <_fini>:
     8048414:	55                   	push   %ebp
     8048415:	89 e5                	mov    %esp,%ebp
     8048417:	53                   	push   %ebx
     8048418:	e8 00 00 00 00       	call   804841d <_fini+0x9>
     804841d:	5b                   	pop    %ebx
     804841e:	81 c3 ff 10 00 00    	add    $0x10ff,%ebx
     8048424:	50                   	push   %eax
     8048425:	e8 aa fe ff ff       	call   80482d4 <__do_global_dtors_aux>
     804842a:	59                   	pop    %ecx
     804842b:	5b                   	pop    %ebx
     804842c:	c9                   	leave  
     804842d:	c3                   	ret    
    
    
    

            由此可见执行程序的最简形式,也是最基本的组成部分:.init段、.plt段、.text段等。

            在此基础之上分别在main函数里添加初始化语句,反汇编之,并利用BCompare等软件对比不同,即可发现初始化语句在反汇编指令中的形式,方便之后对较大程序的反汇编指令阅读。

            以下为本次实验步骤:

            

            这里给出for语句以及调用函数时反汇编指令,初始化、调用系统函数等语句的反汇编,读者可利用main.c和Makefile以及objdump指令自行实验。

            

            

            

    展开全文
  • 常用反汇编命令

    千次阅读 2021-07-22 07:38:49
    gcc 反汇编 arm-none-eabi-objdump.exe -d .\rtthread.elf > rtthread.asm arm-none-eabi-objdump.exe:反汇编用到的编译器 -d :disassemble 表示反汇编 rtthread.elf:表示需要反汇编的文件 rtthread.asm:...

    gcc 反汇编

    arm-none-eabi-objdump.exe -d .\rtthread.elf > rtthread.asm
    
    • arm-none-eabi-objdump.exe:反汇编用到的编译器
    • -d :disassemble 表示反汇编
    • rtthread.elf:表示需要反汇编的文件
    • rtthread.asm:生成的汇编文件的名称(注意前面的 > 符号)

    gcc 反汇编命令帮助

    Usage: arm-none-eabi-objdump.exe <option(s)> <file(s)>
     Display information from object <file(s)>.
     At least one of the following switches must be given:
      -a, --archive-headers    Display archive header information
      -f, --file-headers       Display the contents of the overall file header
      -p, --private-headers    Display object format specific file header contents
      -P, --private=OPT,OPT... Display object format specific contents
      -h, --[section-]headers  Display the contents of the section headers
      -x, --all-headers        Display the contents of all headers
      -d, --disassemble        Display assembler contents of executable sections
      -D, --disassemble-all    Display assembler contents of all sections
      -S, --source             Intermix source code with disassembly
      -s, --full-contents      Display the full contents of all sections requested
      -g, --debugging          Display debug information in object file
      -e, --debugging-tags     Display debug information using ctags style
      -G, --stabs              Display (in raw form) any STABS info in the file
      -W[lLiaprmfFsoRt] or
      --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,
              =frames-interp,=str,=loc,=Ranges,=pubtypes,
              =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,
              =addr,=cu_index]
                               Display DWARF info in the file
      -t, --syms               Display the contents of the symbol table(s)
      -T, --dynamic-syms       Display the contents of the dynamic symbol table
      -r, --reloc              Display the relocation entries in the file
      -R, --dynamic-reloc      Display the dynamic relocation entries in the file
      @<file>                  Read options from <file>
      -v, --version            Display this program's version number
      -i, --info               List object formats and architectures supported
      -H, --help               Display this information
    

    armcc 反汇编

    D:\SoftWare_Application\Keil_MDK_5.32\ARM\ARMCC\bin\fromelf.exe  -cvd rtthread.elf --output rtthread.asm
    
    • xxx\fromelf.exe :反汇编用到的编译器
    • c: disassemble code 反汇编代码
    • v: verbose 详细的
    • d: print contents of data section 打印数据段信息
    • rtthread.elf: 需要反汇编的输入文件
    • –output: 指定输出文件的命令
    • rtthread.asm: 生成的汇编文件

    armcc 反汇编帮助命令

    fromelf [options] input_file
    
    Options:
           --help         display this help screen
           --vsn          display version information
           --output file  the output file. (defaults to stdout for -text format)
           --nodebug      do not put debug areas in the output image
           --nolinkview   do not put sections in the output image
    
    Binary Output Formats:
           --bin          Plain Binary
           --m32          Motorola 32 bit Hex
           --i32          Intel 32 bit Hex
           --vhx          Byte Oriented Hex format
    
           --base addr    Optionally set base address for m32,i32
    
    Output Formats Requiring Debug Information
           --fieldoffsets Assembly Language Description of Structures/Classes
           --expandarrays Arrays inside and outside structures are expanded
    
    Other Output Formats:
           --elf         ELF
           --text        Text Information
    
                    Flags for Text Information
                    -v          verbose
                    -a          print data addresses (For images built with debug)
                    -c          disassemble code
                    -d          print contents of data section
                    -e          print exception tables
                    -g          print debug tables
                    -r          print relocation information
                    -s          print symbol table
                    -t          print string table
                    -y          print dynamic segment contents
                    -z          print code and data size information
    
    展开全文
  • 1、反汇编的原理&为什么需要反汇编 ARM-linux-objdump -D led.elf > led_elf.dis objdump是gcc工具链中的反汇编工具,作用是由编译链接好的elf 格式的可执行程序,来反过来得到汇编源代码。 -D表示反汇编。 >...
  • 大型的非结构化反汇编指令堆几乎不可能被分析,所以大多数反汇编工具都会以某种简单的分析方法来构造反汇编代码。在本节中,我们将会讨论通过反汇编工具恢复的通用代码和数据结构,以及这些通用代码和数据结构会如何...

    大型的非结构化反汇编指令堆几乎不可能被分析,所以大多数反汇编工具都会以某种简单的分析方法来构造反汇编代码。在本节中,我们将会讨论通过反汇编工具恢复的通用代码和数据结构,以及这些通用代码和数据结构会如何帮助我们进行二进制分析。

    6.3.1 构建代码

    首先,我们来看一下构建反汇编代码的各种方法。笼统地说我将向你展示两种使得代码更易于分析的代码结构。

    (1)分块:将代码分成逻辑连接的块,可以更轻松地分析每个块的功能和代码块之间的关系。

    (2)揭示控制流:接下来讨论的这种代码结构不仅表达了代码自身,还很直观地表达了代码块之间的控制流转移,从而更容易快速地查看控制流如何在代码中流动,增加对代码的理解。

    下面的代码结构在自动化和手动分析中都有非常重要的作用。

    1.函数

    在大多数高级编程语言中,如C、C++、Java、Python等,函数是用于对逻辑连接的代码进行分组的基本构建块。众所周知,结构良好且正确划分函数的程序比结构性较差的、含“意大利面条式的代码”的程序更易于理解,所以大多数反汇编工具会花费很大力气来恢复原始程序的函数结构,并对反汇编的指令按照函数进行分组,这就叫函数检测。函数检测不仅仅有助于我们的逆向工程师理解代码,并且还有助于自动化分析,如在二进制自动化分析中,函数检测使我们可以按照函数级别搜索bug或者修改代码,在每个函数的开始和结束时进行特定的安全检查。

    对于具有符号信息的二进制文件,函数检测很简单,符号表指定了函数集,以及它们的名称、起始地址和大小。不幸的是,许多二进制文件的这些信息都被剥离了,这使得函数检测更具挑战性。源代码中的函数放到二进制文件里面是没有任何实际意义的,因为在编译过程中它们的边界可能变得很模糊,特定函数的代码甚至不会连续排列在二进制文件里面,函数的各种细节可能散落在代码段的各个部分,甚至可以在函数之间共享代码块,这也被称为代码块重叠。在实践中,大多数反汇编工具都假设函数是连续的,并且相互间不共享代码,在很多情况(并非所有情况)下这是成立的,但如果分析的是诸如系统固件或者嵌入式系统的代码,那么这是不成立的。

    反汇编工具用于函数检测的主要策略基于函数签名,函数签名通常是在函数开始或结束时使用的指令模式。所有递归反汇编工具,包括IDA Pro都使用此策略。像objdump这样的线性反汇编工具通常不进行函数检测,除非符号可用。

    通常来说,反汇编二进制文件通过基于签名的函数检测算法,来定位由call指令直接寻址的函数。对反汇编工具来说找出这些直接调用很容易,找出间接调用或者尾部调用的函数(tail-called)更具挑战性,[5]具有签名的函数检测器会查询已有的函数签名数据库来找出这些具有挑战性的函数。

    函数签名模式包括已知的函数序言(用于设置函数栈帧的指令)和函数结尾(用于拆除栈帧),如许多x86编译器为未优化的函数生成的典型模式,开头的函数序言都是push ebp;mov ebp,esp,并且函数结尾是leave;ret。很多函数检测器会在二进制文件中扫描此类签名,并且用它们来识别函数的开始和结束位置。

    尽管函数是构造反汇编代码最基础、有用的方法,但始终需要注意错误。在实践中,函数模式非常依赖于平台、编译器以及优化级别来创建二进制文件。优化后的函数可能完全没有已知的函数序言或者结尾,因此无法使用基于签名的方法来识别它们,导致函数检测经常发生错误,如在反汇编工具里面,经常会有20%或者更高概率出现函数起始地址错误的情况,甚至在不是函数的地方报告存在函数。

    最近的研究探索了不同的函数检测方法,这些方法都不是基于签名的,而是基于代码结构的。尽管该方法可能比基于签名的方法更准确,但是检测错误依然存在。目前这种方法已经集成到Binary Ninja里面,原型研究工具可以与IDA Pro进行相互操作,所以可以尝试一番。



     

    使用.eh_frame节进行函数检测

    ELF二进制文件的函数检测有一种有趣的、基于.eh_frame节的替代方法,你可以使用它来解决函数检测遇到的问题。.eh_frame节包含与基于DWARF的调试功能有关(如栈展开)的信息,包括标识二进制文件中所有函数的函数边界信息。除非二进制文件是使用GCC的
    -fno-asynchronous-unwind-tables标志编译的,否则该信息甚至存在于剥离的二进制文件中。.eh_frame主要用于C++的异常处理,当然还包括其他各种应用程序,如backtrace()、GCC内建函数__attribute__((__cleanup__(f)))及__builtin_return_address(n)。由于.eh_frame的用途广泛,因此默认情况下,不仅使用异常处理的C++二进制文件中存在.eh_frame,而且在GCC生成的所有二进制文件,包括纯C二进制文件中都存在.eh_frame。

    据我所知,这种方法最初是由Ryan O’Neill(又名ElfMaster)提出的,其在网站上提供了代码,将.eh_frame节解析为一组函数地址和大小。



     

    2.控制流图

    在将反汇编后的代码分解为函数时,某些函数相当庞大,这意味着即使分析一个函数也可能是一项复杂的任务。为了组织每个函数的内部,反汇编工具和二进制分析框架使用另一种代码结构,该代码结构称为控制流图(Control-Flow Graph,CFG)。CFG可用于自动化分析和手动分析,同时还提供了方便的代码结构表示图形,使你一眼就可以轻松了解函数的内部结构。图6-5显示了使用IDA Pro反汇编函数的CFG示例。

    图6-5 使用IDA Pro反汇编函数的CFG示例

    如图6-5所示,CFG将函数内的代码表示为一组代码块(称为基本块),这些代码块被分支边缘连接,图中用箭头表示。基本块就是一串指令序列,其中第一条指令是唯一的入口点,是二进制中必定要经过的指令,而最后一条指令则是唯一的出口点,是唯一可以跳转到其他基本块的指令。换句话说,你看不到任何一个带有箭头的基本块连接到除了第一条或最后一条指令外的其他任何指令。

    在CFG中,基本块B指向基本块C的箭头意味着B中的最后一条指令可能会跳转到C的起始位置。如果B只有一个出口边缘,意味着它一定会将控制权转移到该边缘的目标代码,这就是间接跳转或者call指令后你将会看到的内容。如果B以条件跳转结束,它就会有两个出口边缘,而采用哪个出口边缘完全取决于运行时跳转条件的结果。

    调用边缘不是CFG的一部分,因为它们的目标是函数外部的代码。相反,CFG只显示“fallthrough”边缘,该箭头指向函数调用完成后返回的指令。另外还有一种称为调用图的代码结构,该代码结构用箭头来表示call指令与函数之间的关系。下面我们来介绍一下调用图。

    实际上,反汇编工具通常会从CFG中忽略间接调用,因为很难静态地解决此类调用的潜在目标。反汇编工具甚至还会定义全局CFG,而不是按每个函数定义CFG,这样的全局CFG称为过程间CFG(ICFG),因为实质上它是所有函数CFG的并集(过程是函数的另一种说法)。ICFG避免了易于出错的函数检测的需要,但其没有提供每个函数CFG所拥有的分隔优势。

    3.调用图

    调用图类似于CFG,不同之处在于调用图显示了调用地址与函数之间的关系,而不是基本块。换句话说,CFG向你展示控制流如何在函数内流动,而调用图则向你展示哪些函数可以相互调用。与 CFG 一样,因为无法根据给定的间接调用地址确定可以调用哪些函数,所以调用图通常会省略间接调用的箭头。

    图6-6的左侧显示了一组函数(标记为

    )以及它们之间的调用关系。每个函数由一些基本块(灰色圆圈)和分支边缘(箭头)组成,对应的调用图在该图的右侧。如图6-6的右侧所示,调用图包含每个函数的节点,并且箭头显示函数

    可以调用

    ,函数

    也可以调用

    。尾部调用(实际上为跳转指令)在调用图中显示为常规调用,但是需要注意的是,从

    的间接调用未在调用图上显示。

    IDA Pro还可以显示部分调用图,该图仅显示你所选择的特定函数的潜在调用者。对手动分析来说,部分调用图比完整调用图更有用,因为完整调用图通常包含太多消息。图6-7显示了IDA Pro中部分调用图的示例,其中显示了对函数sub_404610的引用。如图6-7所示,部分调用图显示了函数是从何处调用的,如函数sub_404610是被函数sub_4E1BD0调用的,而sub_4E1BD0又是被函数sub_4E2FA0调用的。

    图6-6 CFG和函数之间的连接(左)与对应的调用图(右)

    图6-7 IDA Pro中部分调用图的示例

    另外,IDA Pro中部分调用图显示了将函数地址存储在某处的指令。如在.text节的地址0x4E072C处,有一条指令将函数sub_4E2FA0的地址存储在内存中,称为获取sub_4E2FA0函数的地址,而这个地址在代码中任意位置的函数称为地址获取函数(address-taken function)。

    对我们来说,知道哪个函数是地址获取函数非常有用,因为即使不知道准确的函数地址,地址获取函数也会告诉你可以间接地调用它。如果某个函数的地址从来没有被获取,并且没有出现在任何数据节中,你就应该知道该函数不可能被间接调用。[6]这对某些二进制分析或者安全应用程序来说非常有用,如通过限制间接调用只能是合法的目标,来达到保护二进制文件的目的。

    4.面向对象的代码

    现实中你会发现许多二进制分析工具和功能齐全的反汇编工具(如IDA Pro),都是针对面向过程语言(如C)编写的程序。因为代码主要是通过使用这些语言中的函数来构造的,所以二进制分析工具和反汇编工具提供了诸如函数检测的功能,来恢复程序中的函数结构,并且通过调用图来检查函数之间的调用关系。

    面向对象的语言(如C ++)是通过将连接的函数和数据逻辑分成各个类来构造代码的。面向对象语言通常还提供复杂的异常处理功能,该功能允许任何指令抛出异常,然后由处理该异常的特殊代码块来捕获异常。不幸的是,目前的二进制分析工具缺乏恢复类层次结构和异常处理结构的能力。

    更糟糕的是,由于虚函数的实现,C++程序通常包含很多函数指针。虚函数允许在派生类中重写类方法(函数)。在经典实例中,你可以定义一个名为Shape的类,该类有一个名为Circle的派生类,并在Shape中定义了一个名为area的虚函数,该虚函数计算图形的面积,而Circle则通过适用于自身圆形的实现重写了该方法。

    在编译C++程序时,编译器在运行时可能不知道指针到底是指向基本的Shape对象还是派生的Circle对象,因此它无法静态地确定在运行时应该使用area方法的哪种实现。为了解决此问题,编译器制定了称为vtable的函数指针表,其中包含了指向某个类的所有虚函数指针。vtable通常只保存在只读内存中,每个多态对象都有一个指向该对象类型的vtable指针(称为vptr)。为了调用虚函数,编译器会在运行时制定跟随对象vptr指针的代码,并且间接调用在vtable中的正确条目。不幸的是,所有的这些间接调用使程序的控制流变得更难跟踪。

    一般来说,二进制分析工具和反汇编工具缺少对面向对象程序的支持,这意味着如果希望围绕类层次结构进行分析,就只能靠自己了。手动对C++程序进行逆向分析时,通常需要将属于不同类的函数和数据结构组合在一起,但这需要大量的工作。因为我们这里需要重点介绍关于(半)自动化二进制分析的内容,对C++逆向分析的内容不会进行过多介绍。如果对如何手动逆向分析C++代码感兴趣,建议你阅读埃勒达德·艾拉姆(Eldad Eilam)的著作《Reversing:逆向工程揭密》。

    在二进制自动分析的情况下,你可以(如同大多数二进制分析工具)简单假设类不存在,并将面向对象语言的程序与面向过程语言的程序一样对待。而事实上,这种“解决方案”足以应对各种分析,除非确实有必要,否则你也不需要为实现一个特别的C++逆向支持插件而苦恼。

    6.3.2 构建数据

    如你所见,反汇编工具会自动识别各种类型的代码结构,帮助你进一步分析。不幸的是,数据结构却不能被自动识别,因为被剥离的二进制文件中的数据结构,想被自动化检测出来是一个众所周知的难题。除了网络上看到的一些研究[7]以外,反汇编工具基本不会去自动识别数据结构。

    但是也有例外,如果将某个数据对象的引用传递给已知的函数,如库函数,类似IDA Pro的反汇编工具是可以根据库函数的规范自动推断数据类型的。图6-8显示了一个IDA Pro根据send函数的使用自动推断出数据类型的示例。

    图6-8 IDA Pro根据send函数的使用自动推断出数据类型

    在基本块底部附近,有一个通过网络发送消息的已知函数调用。因为IDA Pro知道send函数的参数,所以它可以标记参数名称(flags、len、buf、s),并且推断出用来加载参数的寄存器和内存对象的数据类型。

    此外,原始类型可以通过保存的寄存器或处理数据的指令进行推断。如果你看到使用的是浮点寄存器或运算指令,说明这里的数据类型就是浮点型,如果你看到的是lodsb(加载字符串字节)或stosb(存储字符串字节)指令,那么这里很可能在进行字符串操作。

    对于结构体或者数组之类的复合类型,所有猜测都没有用,你需要自己分析。作为解释很难自动化识别复合类型的一个示例,我们来看一下如何将下面的C代码编译为机器语言:

    ccf->user = pwd->pw_uid;

    上面的代码来自Nginx-1.8.0源代码中的一行,其中将某个结构体的整数字段分配给另一个结构体的字段。在优化级别为-O2的情况下使用GCC v5.1进行编译时,会生成以下汇编代码:

    mov eax,DWORD PTR [rax+0x10]
    mov DWORD PTR [rbx+0x60],eax

    现在我们来看下一行代码,该代码将堆分配的整数b复制到另一个数组a:

    a[24] = b[4];

    下面是用GCC v5.1 优化级别-O2编译的结果:

    mov eax,DWORD PTR [rsi+0x10]
    mov DWORD PTR [rdi+0x60],eax

    从上面两个示例中可以看出,代码模式和结构体的分配完全相同!这表明,任何自动化分析都无法通过一系列这样的指令来判断它们的目的是数组查找、结构体访问,还是其他。这类问题的存在使得很难准确地检测复合数据类型,即使在一般情况下也几乎不可能。虽然上面的示例非常简单,但试想一下我们需要逆向一个包含结构体数组或者是嵌套的结构体,并且试图找出哪条指令索引了哪个数据结构,显然这是一项复杂的任务,需要对代码进行深入分析。由于准确识别这些非常规的数据类型的复杂度很高,所以反汇编工具根本不会对数据结构进行自动化检测。

    为了便于手动构建数据,IDA Pro允许你自定义复合类型(通过逆向代码来推断),并且将它们分配给数据项。克里斯·伊格尔的《IDA Pro权威指南》(第2版)(人民邮电出版社,2012年)是使用IDA Pro手动逆向数据结构的重要资源。

    6.3.3 反编译

    顾名思义,反编译工具就是尝试“逆向编译过程”的工具。它们通常从反汇编代码开始,然后将其翻译成高级语言,类似于C的伪代码。在逆向大型程序的时候,反编译工具很有用,因为反编译后的代码比许多汇编指令易于阅读。但是反编译工具仅限于手动逆向,因为反编译的过程太容易出错,无法为任何自动化分析提供可靠基础。尽管我们不会在本书中用到反编译的功能,但我们还是需要了解一下反编译后的代码的样子,如清单6-6所示。

    这里使用的反编译工具是IDA Pro自带的插件Hex-Rays[8],清单6-6显示了图6-5所示函数用Hex-Rays反编译后的输出。

    清单6-6 函数用Hex-Rays反编译后的输出

    ❶ void ** __usercall sub_4047D4<eax>(int a1<ebp>)
      { 
    ❷    int v1; // eax@1
         int v2; // ebp@1
         int v3; // ecx@4
         int v5; // ST10_4@6
         int i; // [sp+0h] [bp-10h]@3
    
    ❸    v2 = a1 + 12;
         v1 = * (_DWORD * )(v2 - 524);
         * (_DWORD * )(v2 - 540) = * (_DWORD * )(v2 - 520);
    ❹    if ( v1 == 1 )
           goto LABEL_5;
         if ( v1 != 2 )
         {
    ❺      for ( i = v2 - 472; ; i = v2 - 472 )
           {
              * (_DWORD * )(v2 - 524) = 0;
    ❻         sub_7A5950(i);
              v3 = * (_DWORD * )(v2 - 540);
              * (_DWORD * )(v2 - 524) = -1;
              sub_9DD410(v3);
      LABEL_5:
              ;
           }
         }
         * (_DWORD * )(v2 - 472) = &off_B98EC8;
         * (_DWORD * )(v2 - 56) = off_B991E4;
         * (_DWORD * )(v2 - 524) = 2;
         sub_58CB80(v2 - 56);
         * (_DWORD * )(v2 - 524) = 0;
         sub_7A5950(v2 - 472);
         v5 = * (_DWORD * )(v2 - 540);
         * (_DWORD * )(v2 - 524) = -1;
         sub_9DD410(v5);
    ❼    return &off_AE1854;
      }

    从清单6-6中可以看出,反编译后的代码比原始汇编代码更容易阅读,反编译工具会猜测函数的签名❶和局部变量❷。此外,使用C的常规运算符❸替代汇编助记符可以更直观地表示算术和逻辑运算。反编译工具还会尝试重建控制流的构造,如if/else的分支❹、循环❺、函数调用❻,以及C风格的return语句,从而更轻松地得知函数的最终结果❼。

    尽管上述所有这些功能都很有用,但是请记住,反编译只不过是帮助你理解程序正在做什么的一款工具,反编译后的代码可能与原始代码相差甚远,甚至有明显错误,并且受到底层反汇编不准确和反编译过程本身不准确的影响。因此,在反编译的基础上进行更高级的分析通常不是一个好主意。

    6.3.4 中间语言

    诸如x86和ARM之类的指令集包含许多具有复杂语义的不同指令。在x86上,看似简单的指令(如add)也会产生副作用,如在eflags寄存器中设置状态标志,大量的指令及其产生的副作用使得二进制程序很难实现自动化分析。我们会在第10章~第13章看到,动态污点分析和符号执行引擎必须实现显式处理程序,以捕获其分析的所有指令的数据流语义,而准确地实现所有这些处理程序是一项艰巨的任务。

    中间表示(Intermediate Representation,IR),又名中间语言,旨在减轻由此带来的负担。IR是一种简单的语言,可以作为x86和ARM等底层机器语言的抽象。目前流行的IR包括逆向工程中间语言(Reverse Engineering Intermediate Language,REIL)和VEX IR(在valgrind工具框架中使用的IR),还有一个名为McSema的工具,它可以将二进制文件转换为LLVM位码(也称为LLVM IR)。

    IR语言将真实的机器码(如x86代码)自动转换为IR,该IR可以捕获所有机器码的语义,分析起来会简单很多。为了比较,REIL仅包含17条不同的指令,而x86则包含数百条指令,而且,诸如REIL、VEX和LLVM IR之类的语言可以明确表达所有指令操作,而不会产生明显的指令副作用。

    从低级机器码到IR代码的转换需要大量工作,但是一旦完成,在转换后的代码上进行二进制分析就会简单很多。通常只需使用IR实现一次代码转换,而不必为每个二进制分析编写特定指令的处理程序。此外,你可以为许多ISA(如x86、ARM及MIPS)编写转换器,并将它们全部映射到同一IR,这样在该IR上运行的任何二进制分析工具都会自动继承该IR对所有ISA的支持。

    之所以将复杂的指令集(如x86)转换为简单的语言如REIL、VEX或者LLVM IR,是因为 IR 语言远比复杂指令集要简洁得多,这是用有限数量的简单指令表达复杂操作(包括所有副作用)的固有结果。对自动化分析(的计算机)而言,IR的理解通常不会有什么问题,但对个人来说,IR确实令人难以理解。这里为了让大家对IR有比较直观的认识,我们来看清单6-7,其显示了如何将x86-64指令add rax,rdx转换为VEX IR。

    清单6-7 将x86-64指令add rax,rdx转换为VEX IR

    ❶ IRSB {
    ❷    t0:Ity_I64 t1:Ity_I64 t2:Ity_I64 t3:Ity_I64
    
    ❸    00 | ------ IMark(0x40339f, 3, 0) ------
    ❹    01 | t2 = GET:I64(rax)
         02 | t1 = GET:I64(rdx)
    ❺    03 | t0 = Add64(t2,t1)
    ❻    04 | PUT(cc_op) = 0x0000000000000004
         05 | PUT(cc_dep1) = t2
         06 | PUT(cc_dep2) = t1
    ❼    07 | PUT(rax) = t0
    ❽    08 | PUT(pc) = 0x00000000004033a2
         09 | t3 = GET:I64(pc)
    ❾    NEXT: PUT(rip) = t3; Ijk_Boring
         }

    如清单6-7所示,单条add指令就生成了10条VEX指令和一些元数据。首先,有些元数据可能是IR超级块(IR SuperBlock,IRSB)❶,它们对应着单条机器指令。IRSB包含4个标记为t0~t3的临时值,并且它们的类型均为Ity_I64(64位整数)❷。然后是IMark❸,该元数据表示机器指令的地址和长度。

    接下来是对add指令进行建模的实际IR指令。首先,有两条GET指令从rax和rdx分别提取64位值,并临时存储到t2和t1中❹。需要注意,这里的rax和rdx只是这些寄存器在VEX状态建模的符号名称,VEX指令不会从真实的rax或者rdx寄存器中获取数据,而是从这些寄存器的VEX镜像状态中获取数据。为了执行实际的加法运算,IR使用VEX的Add64指令,将两个64位整数t2和t1相加,并将结果存储在t0中❺。

    加法运算后,会有一些PUT指令模拟add指令的副作用,如更新x86状态标志位❻。然后,另一条PUT指令将相加后的结果存储到代表rax❼寄存器的VEX状态。最后,VEX IR模型将程序计数器(PC)更新为下一条指令❽。Ijk_Boring(jump kind boring)❾是一种控制流提示,表示add指令不会以任何有趣的方式影响控制流;因为add操作不属于任何分支,所以控制流只会“掉入”内存中的下一条指令;相反,分支指令可以使用诸如Ijk_Call或Ijk_Ret之类的提示标记,来通知分析正在发生调用或返回。

    在现有二进制分析框架上实现工具时,通常来说无须处理IR,框架会在内部处理所有与IR相关的内容。然而,如果你打算自己实现二进制分析框架,或者修改现有的二进制分析框架,那么了解IR是很有必要的。

    本文摘自《二进制分析实战》

    如今,读者可以找到许多关于汇编的书籍,甚至可以找到更多有关ELF和PE二进制格式的说明。关于信息流跟踪和符号执行也有大量的文章。但是,没有哪本书可以向读者展示从理解基本汇编知识到进行高级二进制分析的全过程。也没有哪本书可以向读者展示如何插桩二进制程序、如何使用动态污点分析来跟踪程序执行过程中的数据或使用符号执行来自动生成漏洞利用程序。换句话说,直到现在,没有一本书可以教你二进制分析所需的技术、工具和思维方式。

    展开全文
  • Win32反汇编(一) 初步探索Win32反汇编 与 Ollydbg的简单使用 文章目录 EAX相关寄存器的结构 MOVSX与MOVZX扩展转移指令 LEA取地址指令 SUB减法指令 CMP与转移指令的配合使用 OD 使用情况小结 ...
  • 文章目录ARM 汇编指令集ARM 指令集分类ARM 指令编码ARM 指令格式解析常见 ARM 指令数据处理与杂项指令加载存储指令其他指令 ARM 汇编指令集 Android 平台的 ARM 汇编指令集根据架构支持类型的不同可分为四大类: ...
  • linux反汇编简单示例

    2021-07-29 09:59:06
    在复杂比较难的程序中比如内核调试,会用到反汇编调试,当程序遇到一些未知的变量错误等,可以直接反汇编来查看汇编代码,一切一目了然。这里介绍一个反汇编的使用方法 需要用到的工具 objdump objdump安装 ubuntu...
  • (5)目标代码及其地址是以注释的形式标注在每条指令后面,文件内容排列也非常整齐,既便于对程序的分析,又不影响直接将反汇编所得到的汇编程序用于编译。 2. 缺点: (1)对于数据块的识别还不够真正智能,使用时...
  • VS 反汇编方法及常用汇编指令介绍

    万次阅读 多人点赞 2017-05-30 17:38:51
    在调试没有源码的文件时,我们可能要用到反汇编设计。 ...一、VS反汇编方法 ...在调试的过程中,按照 调试—>窗口->反汇编 调出反汇编界面 结果如下 这样就可以看到相应的汇编代码了
  • RISCV--汇编指令

    2022-01-26 15:29:26
    相当于csrrw zero,csr,rs1 csrc csr, rs1 根据rs1中的值按位对csr的值清0,相当于csrrc zero,csr,rs1 csrs csr, rs1 根据rs1的值按位对csr的值置1,相当于csrrs zero,csr,rs1 以 i 结尾的伪指令,都是立即数指令,用...
  • C语言实现反汇编【微机原理】
  • objdump(Linux)反汇编命令使用指南

    千次阅读 2021-05-17 19:40:45
    1 objdump反汇编示例1.1 显示main.c的汇编代码1.2 目标文件反汇编1.3 可执行文件反汇编1.4 objdump反汇编常用参数2 objdump帮助信息3 参考资料1 objdump反汇编示例源文件main.c:/* main.c */#includevoid swap(int*...
  • 初级反汇编视频教程【10集】资源目录:【】初级反汇编视频教程全10集-第10节汇编反C语言练习【】初级反汇编视频教程全10集-第1节准备工作【】初级反汇编视频教程全10集-第2节常用汇编指令【】初级反汇编视频教程...
  • V1.23.01相对上一版本,提供ELF文件指令修改,修复ARM MLS指令反汇编错误等BUG;V1.23.00相对上一版本,提供程序地址对应源代码行查询,修复MIPS调试信息错误;V1.22相对上一版本,修复MIPS小端字节序反汇编错误,...
  • 汇编指令外,反汇编窗口还可显示下列可选信息: 每条指令所在的内存地址 对于本机应用程序,它是实际内存地址。 对于 Visual Basic 或 C#,它是距离函数开头的偏移量。 程序集代码派生于的源代码。 代码字节,...
  • 指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构.这里例子中指定反汇编得到的目标文件使用ARM架构。 -b bfdname ...
  • C语言函数反汇编

    千次阅读 2022-03-24 23:28:58
    C语言函数反汇编 ​ 从反汇编的角度,看C是怎么创建函数的。在创建函数的过程中系统做了哪些准备,数据被存放在那里,又是如何完成函数操作的,参数与局部变量在底层硬件中又是怎么流动的? 函数的创建与堆栈操作...
  • C#反汇编,......;
  • 二、使用 GDB 进行程序基本的程序调试以及一些常用的调试指令 三、编译目标代码(.o文件) 一、简单C程序的编译与执行 使用“gedit hello.c”命令在主文件夹下创建一个 hello.c ,也可以选择输入"cd 桌面/test...
  • linux内核反汇编文件

    2020-05-17 17:32:15
    使用objdump指令反汇编出的linux文件,方便学习linux启动流程分析,本内核在实际产品中应用,已经量产,可使用nodepad++打开查看,也可以用文本编辑器查看
  • 汇编指令查询器 反汇编等工具的压缩包 汇编指令查询器 反汇编等工具的压缩包

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,335
精华内容 22,534
关键字:

反汇编指令