现在我遇到了问题。我的项目在汇编级别上工作。 所以我需要汇编级编程,但项目规模太大,无法仅在汇编级工作。由于这个问题,我确定从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
答案 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
之类的命令,或通过libelf
或libbfd
之类的库来解析
或者仅使用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
选项编译您的程序。