- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我了解Polymorphic 和Metamorphic 代码的概念,但是最近我同时阅读了两者的Wikipedia页面(出于某种原因,我以前没有这样做过!)。现在,我真的很想为自己编写一些变形代码。
我是一个精通语言的大师,也是许多人的涉猎者。我知道一些PHP,MySQL,c / c++,Java,Bash脚本,Visual Basic 6,VBScripting,Perl,JavaScript。
有人可以使用任何一种语言提供变形代码的示例。我想看到一个有效的示例,即使程序的输出只是“Hello World”,也要通过示例来了解它是如何发生的(我正在努力理论化如何仅通过思维就能实现这些技术)。任何一种语言都可以做到,那些只是首选。
此外,在Internet上搜索仅返回了数量有限的c / c++示例(甚至没有完整的工作示例,更多的是部分代码片段),这是因为我建议的其他语言的层次不足以具有强大的功能/制作变形代码所需的灵活性?
最佳答案
以下是我认为可以归类为用C编写的变形代码的示例。恐怕我没有大量编写可移植C代码的经验,因此可能需要进行一些修改才能在其他平台上编译(我m使用Windows上的旧版Borland)。而且,由于它涉及某些机器代码生成,因此它依赖于目标平台为x86。从理论上讲,它应该可以在任何x86 OS上进行编译。
工作原理
每次运行该程序时,它都会使用不同的文件名生成自己的随机修改副本。它还会打印出已修改的偏移量列表,以便您可以看到它实际上在做什么。
修改过程非常简单。只是使用汇编指令序列来解释源代码,而汇编指令序列实际上什么也不做。当程序运行时,它会找到这些序列,并用不同的代码随机替换它们(显然也没有执行任何操作)。
硬编码偏移量列表对于其他人需要能够编译的东西显然是不现实的,因此序列的生成方式使其易于在目标代码的搜索中识别,希望不会与任何误报相匹配。
每个序列都从对某个寄存器的推入操作,一组修改该寄存器的指令开始,然后是将寄存器恢复到其初始值的弹出操作。为了简单起见,在原始源代码中,所有序列都是PUSH EAX
,八个NOP
和POP EAX
。不过,在该应用的所有后续版本中,这些序列都是完全随机的。
解释代码
我将代码分为多个部分,因此我可以尝试逐步解释它。如果您想自己编译,则只需将所有部分结合在一起。
首先,一些相当标准的包括:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
PUSH
定义(
0x50
)本身就是
PUSH EAX
,但是您可以通过添加0到7范围内的偏移量来导出其他寄存器的值。
POP
和
MOV
也是如此。
#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
const unsigned char prefixes[] = { ADD,AND,XOR,OR,SBB,SUB,0 };
JUNK
是一个宏,可在代码中需要的任何位置插入垃圾操作序列。如前所述,它最初只是写出
PUSH EAX
,
NOP
和
POP EAX
。
JUNKLEN
是该序列中
NOP
的数量-不是序列的全长。
__emit__
是一个伪函数,它将文字值直接注入(inject)目标代码中。我怀疑如果使用其他编译器,可能需要移植。
#define JUNK __emit__(PUSH,NOP,NOP,NOP,NOP,NOP,NOP,NOP,NOP,POP)
#define JUNKLEN 8
unsigned char *code;
int codelen;
JUNK
宏调用。在整个代码中,您将看到更多这些内容。您几乎可以在任何地方插入它们,但是如果您使用的是真正的C编译器(而不是C++),则尝试将它们放在变量声明之前或之间时会抱怨。
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);
}
NOP
,
MOV
还是其他之一。
NOP
只是一个字节。 MOV为五个字节:我们的MOV操作码(添加了reg参数),以及4个随机字节,代表移入寄存器的编号。
0xC0
到
0xFF
范围内的一个字节,其中最低有效3位代表主寄存器-即必须将其设置为
reg
参数的值。
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;
}
}
reg
和
PUSH
操作中识别出
POP
,则此函数可以尝试验证给定
offset
上的指令是否是我们的垃圾操作之一,并且主寄存器是否与给定的
reg
参数匹配。
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;
}
PUSH
设置为相同)在同一寄存器上查找
POP
操作码,然后再查找
JUNKLEN
操作码。
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;
ESP
,则可以安全地跳过它,因为我们永远不会在生成的代码中使用
ESP
(对
ESP
的堆栈操作需要特别考虑,这是不值得的)。
if (reg == 4) continue; /* register 4 is ESP */
POP
组合,我们便尝试读取它们之间的指令。如果我们成功匹配了期望的字节长度,则认为可以替换该匹配。
j = 0; JUNK;
while (inc = readinstruction(reg,i+1+j)) j += inc;
if (j != JUNKLEN) continue; JUNK;
ESP
之前所述),然后在序列的任一端为该寄存器写出
PUSH
和
POP
操作。
reg = rand()%7; JUNK;
reg += (reg >= 4);
code[i] = PUSH+reg; JUNK;
code[i+JUNKLEN+1] = POP+reg; JUNK;
writeinstruction
函数填充它们之间的空间。
space = JUNKLEN;
j = 0; JUNK;
while (space) {
inc = writeinstruction(reg,i+1+j,space); JUNK;
j += inc;
space -= inc; JUNK;
}
printf("%d\n",i); JUNK;
}
}
argv[0]
参数包含应用程序文件名。
int main(int argc, char* argv[]) {
readcode(argv[0]); JUNK;
replacejunk(); JUNK;
writecode(argv[0]); JUNK;
return 0;
}
goto
函数。每行以一个标签开头,并以指向下一行标签的
goto
结尾。这样,每一行基本上都是独立的,我们可以很高兴地对它们进行洗牌,而程序仍然可以像以前一样工作。
关于polymorphism - 变形代码示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10113254/
我尝试理解[c代码 -> 汇编]代码 void node::Check( data & _data1, vector& _data2) { -> push ebp -> mov ebp,esp ->
我需要在当前表单(代码)的上下文中运行文本文件中的代码。其中一项要求是让代码创建新控件并将其添加到当前窗体。 例如,在Form1.cs中: using System.Windows.Forms; ..
我有此 C++ 代码并将其转换为 C# (.net Framework 4) 代码。有没有人给我一些关于 malloc、free 和 sprintf 方法的提示? int monate = ee; d
我的网络服务器代码有问题 #include #include #include #include #include #include #include int
给定以下 html 代码,将列表中的第三个元素(即“美丽”一词)以斜体显示的 CSS 代码是什么?当然,我可以给这个元素一个 id 或一个 class,但 html 代码必须保持不变。谢谢
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我试图制作一个宏来避免重复代码和注释。 我试过这个: #define GrowOnPage(any Page, any Component) Component.Width := Page.Surfa
我正在尝试将我的旧 C++ 代码“翻译”成头条新闻所暗示的 C# 代码。问题是我是 C# 中的新手,并不是所有的东西都像 C++ 中那样。在 C++ 中这些解决方案运行良好,但在 C# 中只是不能。我
在 Windows 10 上工作,R 语言的格式化程序似乎没有在 Visual Studio Code 中完成它的工作。我试过R support for Visual Studio Code和 R-T
我正在处理一些报告(计数),我必须获取不同参数的计数。非常简单但乏味。 一个参数的示例查询: qCountsEmployee = ( "select count(*) from %s wher
最近几天我尝试从 d00m 调试网络错误。我开始用尽想法/线索,我希望其他 SO 用户拥有可能有用的宝贵经验。我希望能够提供所有相关信息,但我个人无法控制服务器环境。 整个事情始于用户注意到我们应用程
我有一个 app.js 文件,其中包含如下 dojo amd 模式代码: require(["dojo/dom", ..], function(dom){ dom.byId('someId').i
我对“-gencode”语句中的“code=sm_X”选项有点困惑。 一个例子:NVCC 编译器选项有什么作用 -gencode arch=compute_13,code=sm_13 嵌入库中? 只有
我为我的表格使用 X-editable 框架。 但是我有一些问题。 $(document).ready(function() { $('.access').editable({
我一直在通过本教程学习 flask/python http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-wo
我想将 Vim 和 EMACS 用于 CNC、G 代码和 M 代码。 Vim 或 EMACS 是否有任何语法或模式来处理这种类型的代码? 最佳答案 一些快速搜索使我找到了 this vim 和 thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve this
这个问题在这里已经有了答案: Enabling markdown highlighting in Vim (5 个回答) 6年前关闭。 当我在 Vim 中编辑包含 Markdown 代码的 READM
我正在 Swift3 iOS 中开发视频应用程序。基本上我必须将视频 Assets 和音频与淡入淡出效果合并为一个并将其保存到 iPhone 画廊。为此,我使用以下方法: private func d
pipeline { agent any stages { stage('Build') { steps { e
我是一名优秀的程序员,十分优秀!