通过自修改代码进行动态混淆

这是我想要做的:

假设你有两个function

void f1(int *v) { *v = 55; } void f2(int *v) { *v = 44; } char *template; template = allocExecutablePages(...); char *allocExecutablePages (int pages) { template = (char *) valloc (getpagesize () * pages); if (mprotect (template, getpagesize (), PROT_READ|PROT_EXEC|PROT_WRITE) == -1) { perror (“mprotect”); } } 

我想在f1和f2之间做一个比较(所以告诉什么是相同的,什么不是)(所以得到那些函数的assembly线并逐行比较)然后将这些行放在我的模板中。

在C中有办法做到这一点吗?

谢谢

更新

感谢所有你回答的人,但也许我没有正确解释我的需要。

基本上我正在尝试编写一个小混淆方法。 这个想法包括让两个或多个函数共享内存中的相同位置。 建立一个内存区域(我们将其称为模板),其中包含来自函数的一些机器代码字节,更具体地说,它们都具有共同的机器代码字节。 在执行特定function之前,编辑脚本用于使用必要的机器代码字节修补模板,以创建该function的完整版本。 当即将执行分配给同一模板的另一个函数时,该过程将重复,这次使用不同的编辑脚本。 为了说明这一点,假设您想要混淆包含两个函数f1和f2的程序。 第一个(f1)具有以下机器代码字节

 Address Machine code 0 10 1 5 2 6 3 20 and the second one (f2) has Address Machine code 0 10 1 9 2 3 3 20 At obfuscation time, one will replace f1 and f2 by the template Address Machine code 0 10 1 ? 2 ? 3 20 and by the two edit scripts e1 = {1 becomes 5, 2 becomes 6} and e2 = {1 becomes 9, 2 becomes 3}. #include  #include  typedef unsigned int uint32; typedef char * addr_t; typedef struct { uint32 offset; char value; } EDIT; EDIT script1[200], script2[200]; char *template; int template_len, script_len = 0; typedef void(*FUN)(int *); int val, state = 0; void f1_stub () { if (state != 1) { patch (script1, script_len, template); state = 1; } ((FUN)template)(&val); } void f2_stub () { if (state != 2) { patch (script2, script_len, template); state = 2; } ((FUN)template)(&val); } int new_main (int argc, char **argv) { f1_stub (); f2_stub (); return 0; } void f1 (int *v) { *v = 99; } void f2 (int *v) { *v = 42; } int main (int argc, char **argv) { int f1SIZE, f2SIZE; /* makeCodeWritable (...); */ /* template = allocExecutablePages(...); */ /* Computed at obfuscation time */ diff ((addr_t)f1, f1SIZE, (addr_t)f2, f2SIZE, script1, script2, &script_len, template, &template_len); /* We hide the proper code */ memset (f1, 0, f1SIZE); memset (f2, 0, f2SIZE); return new_main (argc, argv); } 

所以我现在需要编写diff函数。 这将获取我的两个函数的地址,并将生成一个带有相关脚本的模板。

这就是为什么我想比较两个函数的字节数

对不起,我的第一篇文章不是很容易理解!

谢谢

您想在运行时或作者身份期间执行此操作吗?

您可以指示您的C编译器生成汇编语言输出,例如gcc具有-S选项,它将在file.s中生成输出。您的编译器套件也可能有一个程序,如objdump,它可以反编译目标文件或整个可执行文件。 但是,您通常希望将优化保留为现代编译器而不是自己编写。

在运行时,&运算符可以获取函数的地址,并且您可以读取它,尽管您必须为在任何有趣的事情之前遇到分支指令的可能性做好准备,因此您实际上必须以编程方式“理解”至少一个子集指令集。 阅读函数指针时遇到的问题当然会因机器,ABI,编译器,优化标志等而异。

将函数放入t1.ct2.c使用gcc -S生成汇编输出:

 gcc -S t1.c gcc -S t2.c 

现在比较t1.st2.s

如果您使用的是Visual Studio,请转到

 Project Properties -> Configuration -> C/C++ -> Output Files -> Assembler output 

或使用编译器开关/FA/FAc/FAs/FAcs 。 小写c表示输出机器代码, s源代码与汇编代码并排。 并且不要忘记禁用编译器优化。

阅读了一些答案和那里的评论,我不确定我是否完全理解你的问题,但也许你正在寻找如下的gcc调用:
gcc -S -xc - -o -

这告诉gcc从stdin输出C代码并将输出程序集输出到stdout。

如果使用类似vi的编辑器,则可以在可视模式下突出显示函数体,然后运行命令:
:'<,'>!gcc -S -xc - -o - 2> /dev/null
…这将用汇编替换函数体(“stderr> / dev / null”业务是跳过关于#include的错误)。

否则,您可以将此gcc调用用作脚本中管道的一部分。