结构体位操作--反汇编(一)

先看下面的代码:

1 #include <stdio.h> 2 #include <string.h> 3 4 typedef unsigned long ulong; 5 6 struct A 7 { 8 ulong board_type: 1; 9 ulong channel_type: 3; 10 ulong fpga_en : 1; 11 ulong fpga_downloaded: 1; 12 ulong ds26519A_reset: 1; 13 ulong ds26519B_reset: 1; 14 ulong ds26519C_reset: 1; 15 ulong ds26519D_reset: 1; 16 ulong reserved1: 1; //bit 10 17 ulong reset_bcm : 1; 18 ulong reserved2: 4; //bit 12- bit15 19 ulong reserved3: 16; 20 21 }; 22 23 struct A aa; 24 25 int main() 26 { 27 memset(&aa, 0xff, sizeof(struct A)); 28 aa.reserved1= 1; 29 30 return 0; 31 }

 

假定文件名叫test_struct_bitw.c,使用如下命令:

#gcc -o test_struct_bitw test_struct_bitw.c -g
#objdump -d test_struct_bitw > 1.txt

 反汇编生成如下内容(1.txt为了方便阅读,去掉了很多与本文不相关的内容):

 test_struct_bitw: file format elf32-i386 Disassembly of section .text: 08048280 <_start>: 8048280: 31 ed xor %ebp,%ebp 8048282: 5e pop %esi 8048283: 89 e1 mov %esp,%ecx 8048285: 83 e4 f0 and $0xfffffff0,%esp 8048288: 50 push %eax 8048289: 54 push %esp 804828a: 52 push %edx 804828b: 68 60 83 04 08 push $0x8048360 8048290: 68 70 83 04 08 push $0x8048370 8048295: 51 push %ecx 8048296: 56 push %esi 8048297: 68 24 83 04 08 push $0x8048324 804829c: e8 c7 ff ff ff call 8048268 ................. ................. ................. 08048324 <main>: 8048324: 8d 4c 24 04 lea 0x4(%esp),%ecx 8048328: 83 e4 f0 and $0xfffffff0,%esp 804832b: ff 71 fc pushl 0xfffffffc(%ecx) 804832e: 55 push %ebp 804832f: 89 e5 mov %esp,%ebp 8048331: 51 push %ecx 8048332: c7 05 34 95 04 08 00 movl $0xffffffff,0x8049534 8048339: 00 00 00 804833c: 0f b6 05 35 95 04 08 movzbl 0x8049535,%eax 8048343: 83 c8 04 or $0x4,%eax 8048346: a2 35 95 04 08 mov %al,0x8049535 804834b: b8 00 00 00 00 mov $0x0,%eax 8048350: 59 pop %ecx 8048351: 5d pop %ebp 8048352: 8d 61 fc lea 0xfffffffc(%ecx),%esp 8048355: c3 ret 8048356: 90 nop 8048357: 90 nop 8048358: 90 nop 8048359: 90 nop 804835a: 90 nop 804835b: 90 nop 804835c: 90 nop 804835d: 90 nop 804835e: 90 nop 804835f: 90 nop ................. ................. .................

这里我们只关心 aa.reserved1= 1; 这句对应的汇编代码,要用到addr2line。我们从反汇编的内容中可以找到 08048324  <main>: 这句,也就是C代码里main函数入口。凭直觉,可能是 804833c这行,使用命令#addr2line -e test_struct_bitw  0x804833c ,输出结果是test_struct_bitw.c:28。显然,我们找到的这句汇编指令就是对应C代码中的28行 aa.reserved1= 1; ,但是不只这一句。同样使用命令#addr2line -e test_struct_bitw  0x8048343 ,#addr2line -e test_struct_bitw  0x8048346 ,输出结果都是test_struct_bitw.c:28,也就是说 aa.reserved1= 1; 这句C代码对应的汇编代码是三句,即:

804833c: 0f b6 05 35 95 04 08 movzbl 0x8049535,%eax 8048343: 83 c8 04 or $0x4,%eax 8048346: a2 35 95 04 08 mov %al,0x8049535

结合之前的两行代码:

8048332:       c7 05 34 95 04 08 00    movl   $0xffffffff,    0x8049534   

8048339:       00 00 00 

不难看出,就是从0x8049535处取了一个字节(原因是成员reserved1是整个32位成员中的第二个字节,所以地址要从0x8049535开始,同理若是aa.fpga_en= 1;则就应该从0x8049534 处取了),然后进行按位或操作,最后在把位操作后的结果写回到0x8049535地址中去。这里的关键在于要理解  804833c:   0f b6 05 35 95 04 08    movzbl 0x8049535, %eax 这句汇编代码,意思是从0x8049535的内存空间中取一个字节,其余位填0,32位的数据放到eax寄存器中。

操作步骤示意图如下:

 

 

 

你可能感兴趣的:(结构体位操作--反汇编(一))