从GCC获取函数十六进制代码

时间:2015-03-30 07:27:43

标签: c gcc assembly

现在我遇到了问题。我的项目在汇编级别上工作。 所以我需要汇编级编程,但项目规模太大,无法仅在汇编级工作。由于这个问题,我确定从gcc制作的c-source-file获取十六进制码。但怎么样? 如何使用gcc获取某些功能 HEXCODES

我有个主意,

int function_name(){
    int a=1;
    return a;
}
write(fd, (char *)function_name, sizeof(function_name))

在这之后我会得到 function_name 的十六进制代码。 但这并不是解决这个问题的好办法,当我需要很多功能作为目标时,我需要处理很多文件。

还有其他好方法可以解决这个问题吗?我认为理想的解决方案只需要函数名称(如果需要,可以输出文件名)并在命令行上运行。我认为不可能是理想的解决方案吗?

我还假设编译器的优化选项已关闭 所以我会从 function_name 获得十六进制 ' \ x55 \ x8B \ xEC \ x83 \ xEC \ x04 \ xC7 \ x45 \ xFC \ x01 \ X00 \ X00 \ X00 \ x8B \ X45 \ XFC \ x8B \ xE5 \ X5D \ XC3' function_name 的汇编代码如下。

PUSH EBP
MOV EBP, ESP
SUB ESP, 4
MOV DWORD PTR[EBP-4], 1
MOV EAX, DWORD PTR[EBP-4]
MOV ESP, EBP
POP EBP
RETN

3 个答案:

答案 0 :(得分:1)

gcc从每个源文件生成一个汇编文件,作为编译工具链的一部分。该文件通常是临时文件,因此会立即删除。如果您希望将其保存为myfile.s,则可以使用以下命令:

gcc -S -o myfile.s myfile.c

答案 1 :(得分:1)

尝试

objdump -D -Mintel yourfile.o

转储看起来像(.O由免费的pascal编译器生成,但gcc将大致相同)

   0:   55                      push   ebp
   1:   89 e5                   mov    ebp,esp
   3:   8d 64 24 ec             lea    esp,[esp-0x14]
   7:   53                      push   ebx
   8:   89 45 fc                mov    DWORD PTR [ebp-0x4],eax
   b:   c7 45 f4 00 00 00 00    mov    DWORD PTR [ebp-0xc],0x0
  12:   31 c0                   xor    eax,eax
  14:   68 00 00 00 00          push   0x0
  19:   55                      push   ebp
  1a:   68 00 00 00 00          push   0x0
  1f:   64 ff 30                push   DWORD PTR fs:[eax]
  22:   64 89 20                mov    DWORD PTR fs:[eax],esp
  25:   c7 45 f8 00 00 00 00    mov    DWORD PTR [ebp-0x8],0x0
  2c:   8b 45 fc                mov    eax,DWORD PTR [ebp-0x4]
  2f:   8b 50 04                mov    edx,DWORD PTR [eax+0x4] 

代码仍然是可重定位的,因此引用将为零字节。

要解决这个问题,你需要objdump二进制(.exe)而不是.o,但是这样的输出通常很大,并且会使查找特定位置变得更难。

答案 2 :(得分:0)

我猜您使用的是Linux,因为您使用的是gcc

您可以运行

 gcc -Wall -O -c myfile.c

从源C文件myfile.o获取对象文件myfile.c;该对象文件位于ELF中,因此包含特别是二进制代码和relocation订单。您可以解析该ELF对象文件(例如,使用objdump(1)readelf之类的命令,或通过libelflibbfd之类的库来解析

或者仅使用position independent code的ELF共享对象并使用dlopen(3)。见program library howto

请注意,并非每个源级C函数都对应于目标文件中的某些函数(例如ELF符号)(例如,由于static函数 - 它们的名称可能被遗忘或stripped,或者因为inline个函数 - 他们没有拥有的机器代码,调用者已经inlined。假设optimizing compiler(例如gcc -O2)。

请记住,decompilation一般来说是一项不可能完成的任务。请注意halting problem undecidable。{/ p>

另请参阅this question以及有关libopcode

的答案

顺便说一句,

write(fd, (char *)function_name, sizeof(function_name))

不会编译(你无法使用sizeof某些功能)。也许你会这样做

write(fd, (char*)function_name, sizeof(char*))

会写一些地址,这可能没什么意义(请注意ASLR)。

也许你想要dladdr(3)?您可能需要使用在链接时传递的-rdynamic选项编译您的程序。