.byte 这样的指令: asm __volatile __(。byte 0x50,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x58 \); 以下是 godbolt上的现场示例,包括最右边的窗格,它显示它正确地反编译为 push rax ,八 nop s和 pop rax 。 查看更多关于 .byte 指令此处。 然而,这在Raspberry Pi上仍然不起作用,因为这些操作码出现在x86上。您将不得不将它们更改为相应的ARM操作码。此外,GCC是一个高度优化的编译器,你不能用这个代码对旧的Borland C编译器的方式操作C栈。 So I've been working on implementing the metamorphic code example from James Holderness found here: Metamorphic Code Examples.#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <time.h>#define PUSH 0x50#define POP 0x58#define MOV 0xB8#define NOP 0x90#define ADD 0x01#define AND 0x21#define XOR 0x31#define OR 0x09#define SBB 0x19#define SUB 0x29#define JUNK asm __volatile__(PUSH,NOP,NOP,NOP,NOP,NOP,NOP,NOP,NOP,POP)#define JUNKLEN 8const unsigned char prefixes[] = {ADD, AND, XOR, OR, SBB, SUB, 0};unsigned char *code;int codelen;void readCode(const char *filename){ FILE *fp = fopen(filename, "rb"); JUNK; fseek(fp, 0L, SEEK_END); JUNK; codelen = ftell(fp); code = malloc(codelen); JUNK; fseek(fp, 0L, SEEK_SET); fread(code, codelen, 1, fp); JUNK;}void writeCode(const char *filename){ FILE *fp; int lastOffset = strlen(filename) - 1; char lastChar = filename[lastOffset]; char *newFileName = strdup(filename); JUNK; lastChar = '0' + (isdigit(lastChar)?(lastChar - '0' + 1) %10:0); newFileName[lastOffset] = lastChar; fp = fopen(newFileName, "wb"); JUNK; fwrite(code, codelen, 1, fp); JUNK; fclose(fp); free(newFileName);}int writeInstruction(unsigned reg, int offset, int space){ if (space < 2) { code[offset] = NOP; JUNK; return 1; } else if (space < 5 || rand() % 2 == 0) { code[offset] = prefixes[rand() % 6]; JUNK; code[offset + 1] = 0xC0 + rand() % 8 * 8 + reg; JUNK; return 2; } else { code[offset] = MOV + reg; JUNK; *(short *)(code + offset + 1) = rand(); *(short *)(code + offset + 3) = rand(); JUNK; return 5; }}int readInstruction(unsigned reg, int offset){ unsigned c1 = code[offset]; if (c1 == NOP) return 1; JUNK; if (c1 == MOV + reg) return 5; JUNK; if (strchr(prefixes, c1)) { unsigned c2 = code[offset + 1]; JUNK; if (c2 >= 0xC0 && c2 <= 0xFF && (c2 & 7) == reg) return 2; JUNK; } JUNK; return 0;}void replaceJunk(void){ int i, j, inc, space; srand(time(NULL)); JUNK; for (i = 0; i < codelen - JUNKLEN - 2; i++) { unsigned start = code[i]; unsigned end = code[i + JUNKLEN + 1]; unsigned reg = start - PUSH; if (start < PUSH || start >= PUSH + 8) continue; JUNK; if (end != POP + reg) continue; JUNK; if (reg == 4) continue; j = 0; JUNK; while (inc = readInstruction(reg, i + 1 + j)) j = j + inc; if (j != JUNKLEN) continue; JUNK; reg = rand() % 7; JUNK; reg += (reg >= 4); code[i] = PUSH + reg; JUNK; code[i + JUNKLEN + 1] = POP + reg; JUNK; space = JUNKLEN; j = 0; while (space) { inc = writeInstruction(reg, i + 1 + j, space); JUNK; j = j + inc; space = space - inc; JUNK; } printf("%d\n", i); JUNK; }}int main(int argc, char *argv[]){ readCode(argv[0]); JUNK; replaceJunk(); JUNK; writeCode(argv[0]); JUNK; return 0;}I'm attempting to compile using GCC (version 6.3.0) on Raspbian 4.9 but the compile keeps failing and issuing errors "undefined reference to __emit__. Now I know this is because emit is a Borland C Compiler macro and so I've consequently attempted to implement similar functionality using the asm volatile macro found here (Implementing Borland's __emit__ macro in GCC).How can I change the code to work with GCC? I've tried a number of different uses of asm volatile but nothing seems to work. I expect that most of the #defines will have to change, I just don't know the correct way to do it. 解决方案 You can put arbitrary bytes at the location of an asm block using the .byte directive like this:asm __volatile__(".byte 0x50, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x58\n");Here's a live example on godbolt, including the far right pane which shows that it decompiled fine into a push rax, eight nops, and pop rax.See more about the .byte directive here.However, this will still not work on the Raspberry Pi because the opcodes appear to for x86. You will have to change them to the corresponding ARM opcodes. Furthermore, the GCC is a highly optimizing compiler, and you cannot manipulate the C stack in the way this code did with the old Borland C compiler. 这篇关于变形示例代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 阿里云证书,YYDS!
05-24 21:48