Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 变形示例代码_C_Gcc_Assembly_Macros_Inline - Fatal编程技术网

C 变形示例代码

C 变形示例代码,c,gcc,assembly,macros,inline,C,Gcc,Assembly,Macros,Inline,所以我一直致力于实现James Holderness的变形代码示例,该示例在这里找到: #包括 #包括 #包括 #包括 #包括 #定义推送0x50 #定义POP 0x58 #定义MOV 0xB8 #定义nop0x90 #定义添加0x01 #定义和定义0x21 #定义XOR 0x31 #定义或0x09 #定义SBB 0x19 #定义子0x29 #定义垃圾asm\uuuuu volatile\uuuuuuuuuu(推送、NOP、NOP、NOP、NOP、NOP、NOP、POP) #定义容克伦8 常量无

所以我一直致力于实现James Holderness的变形代码示例,该示例在这里找到:

#包括
#包括
#包括
#包括
#包括
#定义推送0x50
#定义POP 0x58
#定义MOV 0xB8
#定义nop0x90
#定义添加0x01
#定义和定义0x21
#定义XOR 0x31
#定义或0x09
#定义SBB 0x19
#定义子0x29
#定义垃圾asm\uuuuu volatile\uuuuuuuuuu(推送、NOP、NOP、NOP、NOP、NOP、NOP、POP)
#定义容克伦8
常量无符号字符前缀[]={ADD,AND,XOR,OR,SBB,SUB,0};
无符号字符*码;
内科德伦;
无效读码(常量字符*文件名)
{
FILE*fp=fopen(文件名,“rb”);垃圾;
fseek(fp,0L,SEEK_END);垃圾;
codelen=ftell(fp);
代码=malloc(codelen);垃圾;
fseek(fp、0L、SEEK\u集);
fread(代码,codelen,1,fp);垃圾;
}
无效写代码(常量字符*文件名)
{
文件*fp;
int lastpoffset=strlen(文件名)-1;
char lastChar=文件名[lastOffset];
char*newFileName=strdup(文件名);垃圾;
lastChar='0'+(isdigit(lastChar)?(lastChar-'0'+1)%10:0);
newFileName[lastOffset]=lastChar;
fp=fopen(newFileName,“wb”);垃圾;
fwrite(code,codelen,1,fp);垃圾;
fclose(fp);
免费(新文件名);
}
整数写入指令(无符号注册表、整数偏移量、整数空格)
{
if(空格<2){
代码[偏移量]=NOP;垃圾;
返回1;
}else if(空格<5 | | rand()%2==0){
代码[偏移量]=前缀[rand()%6];垃圾;
代码[offset+1]=0xC0+rand()%8*8+reg;垃圾;
返回2;
}否则{
代码[偏移]=MOV+reg;垃圾;
*(短*)(代码+偏移量+1)=兰德();
*(短*)(代码+偏移量+3)=兰德();垃圾;
返回5;
}
}
整型读取指令(无符号寄存器,整型偏移量)
{
无符号c1=代码[偏移量];
如果(c1==NOP)
返回1;垃圾;
如果(c1==MOV+reg)
返回5;垃圾;
if(strchr(前缀,c1)){
无符号c2=代码[偏移量+1];垃圾;
如果(c2>=0xC0&&c2=PUSH+8)
继续;垃圾;
如果(结束!=POP+reg)
继续;垃圾;
如果(reg==4)
继续;
j=0;垃圾;
而(inc=读取指令(reg,i+1+j))
j=j+inc;
如果(j!=JUNKLEN)
继续;垃圾;
reg=rand()%7;垃圾;
reg+=(reg>=4);
代码[i]=推送+注册;垃圾;
代码[i+JUNKLEN+1]=POP+reg;垃圾;
空间=容克伦;
j=0;
while(空间){
inc=写指令(reg,i+1+j,空格);垃圾;
j=j+inc;
空间=空间公司;垃圾;
}
printf(“%d\n”,i);垃圾;
}
}
int main(int argc,char*argv[])
{
读码(argv[0]);垃圾;
垃圾;垃圾;
写代码(argv[0]);垃圾;
返回0;
}
我试图在Raspbian4.9上使用GCC(版本6.3.0)进行编译,但编译一直失败并发出错误“未定义对
\uuuuu emit\uuuu
的引用。”。现在我知道这是因为emit是一个Borland C编译器宏,因此我尝试使用这里找到的asmvolatile宏()实现类似的功能


如何更改代码以使用GCC?我已经尝试了asmvolatile的多种不同用法,但似乎没有任何效果。我预计大多数#定义都必须更改,我只是不知道正确的方法。

您可以使用
.byte
指令将任意字节放在
asm
块的位置,如下所示:

asm __volatile__(".byte 0x50, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x58\n");
下面是一个示例,包括最右侧的窗格,其中显示它已将精细反编译为一个
push-rax
、八个
nop
s和
pop-rax

有关
.byte
指令的详细信息,请参阅


但是,这在Raspberry Pi上仍然不起作用,因为操作码似乎是针对x86的。您必须将其更改为相应的ARM操作码。此外,GCC是一个高度优化的编译器,您不能像此代码处理旧Borland C编译器那样操作C堆栈。

除了您已经得到的答案之外,请注意,如果您在Raspberry Pi上使用Raspbian,您可能应该使用ARM操作码,而不是x86操作码。@zneak-oops,对,我没有提到拉斯宾!在这种情况下,整个示例都需要修改,因为整个方法在某种程度上特定于x86操作码。@PeterCordes-仔细看看。我似乎不是非常特定于编译器,它应该主要在x86上“正常工作”。基本上,它不是修改编译器生成的任意代码,而是搜索
asm
宏逐字插入的
JUNK
序列。只要编译器忠实地发出这些序列,它就会找到它们。然后,它以这样一种方式重写这些序列,即它仍然是有效的无操作,但有新的指令。我不认为这有什么大问题。误报的可能性很小:错误地找到
垃圾
签名。@BeeOnRope:但是gcc不知道推送/弹出!这与使用
push%%rbp
/
pop%%rbp
的内联asm将gcc溢出到
-8(%rsp)
的内容击杀的问题是一样的。我想为了确保此代码的安全,您可以将
JUNK
更改为
sub-rsp,128;按rax。。。波普雷克斯;添加rsp 128
,这样您就可以确定您正在避免任何对redzone的攻击。然后我会用“asm”替换代码中的每个“垃圾”实例吗?是否会保留相同的功能?您可以保留相同的垃圾宏,但只需使用
.byte
指令根据
asm
重新定义它即可。通过使用宏字符串化,您可以保持不变<
asm __volatile__(".byte 0x50, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x58\n");