嵌入代码和盗版软件的危险

关于如何在代码部分中嵌入没有jmp的代码,并且如果不学习彻底分解的代码,则保持不可见。 谁在乎,请在猫下。

我正在为Linux开发C反汇编程序。 关于我自己,我不会说我是一名专业程序员。 我不是程序员,但我学到的是读书,自己发明或研究其他程序的源代码。 因此,如果您发现该代码幼稚,请不要发誓。

首先,我做了一个反汇编程序,现在我的代码看起来像这样,即读取了一个字节并将其传递给所需的函数。

void disasm_intel ( unsigned char *ptr, int size, int byte_order, int show ) { show_asm = show; virt = global_virt_text; unsigned char *start = ptr; start_op = ptr; for ( int index = 0; index < size; index++ ) { if ( show_asm == TRUE ) printf ( "%lx: ", virt ); switch ( *ptr ) { case 0x30: intel_opcode_1_0x30 ( &ptr, &index, byte_order ); break; case 0x31: intel_opcode_1_0x31 ( &ptr, &index, byte_order ); break; case 0x66: intel_opcode_1_0x66 ( &ptr, &index, byte_order ); break; case 0x67: intel_opcode_1_0x67 ( &ptr, &index, byte_order ); break; case 0x83: intel_opcode_1_0x83 ( &ptr, &index, byte_order ); break; case 0x88: intel_opcode_1_0x88 ( &ptr, &index, byte_order ); break; // mov register to register byte case 0x89: intel_opcode_1_0x89 ( &ptr, &index, byte_order ); break; case 0x8a: intel_opcode_1_0x8a ( &ptr, &index, byte_order ); break; case 0x8b: intel_opcode_1_0x8b ( &ptr, &index, byte_order ); break; // mov esp, %x : mov ebp, %x case 0x8d: intel_opcode_1_0x8d ( &ptr, &index, byte_order ); break; // lea case 0xb0: intel_opcode_1_0xb0 ( &ptr, &index ); break; // mov al, %x case 0xb1: intel_opcode_1_0xb1 ( &ptr, &index ); break; // mov cl, %x case 0xb2: intel_opcode_1_0xb2 ( &ptr, &index ); break; // mov dl, %x case 0xb3: intel_opcode_1_0xb3 ( &ptr, &index ); break; // mov bl, %x case 0xb4: intel_opcode_1_0xb4 ( &ptr, &index ); break; // mov ah, %x case 0xb5: intel_opcode_1_0xb5 ( &ptr, &index ); break; // mov ch, %x case 0xb6: intel_opcode_1_0xb6 ( &ptr, &index ); break; // mov dh, %x case 0xb7: intel_opcode_1_0xb7 ( &ptr, &index ); break; // mov bh, %x case 0xb8: intel_opcode_1_0xb8 ( &ptr, &index, byte_order ); break; // mov eax, %x case 0xb9: intel_opcode_1_0xb9 ( &ptr, &index, byte_order ); break; // mov ecx, %x case 0xba: intel_opcode_1_0xba ( &ptr, &index, byte_order ); break; // mov edx, %x case 0xbb: intel_opcode_1_0xbb ( &ptr, &index, byte_order ); break; // mov ebx, %x case 0xbe: intel_opcode_1_0xbe ( &ptr, &index, byte_order ); break; // mov esi, %x case 0xbf: intel_opcode_1_0xbf ( &ptr, &index, byte_order ); break; // mov edi, %x case 0xc3: intel_opcode_1_0xc3 ( ); break; // ret case 0xcd: intel_opcode_1_0xcd ( &ptr, &index ); break; // int 0x%x } ptr++; virt += ptr - start; start = ptr; start_op = ptr; } show_asm = FALSE; } 

这样的功能已经是一堆了。 在某些地方,我进行了评论,以了解机器指令的相互联系,也许以后再做一个更有能力的反汇编程序。 但是,以这种形式(现在有代码),我可以轻松地为每个运算符设置任何条件。

因此,当我这样做时,我有了一个主意,是否可以在代码部分的中间添加代码? 事实证明您可以,但是在所有情况下? 到目前为止,要添加代码,我使用已经准备好的机器代码。 如果以后可以,那么我将使汇编程序翻译器在机器代码中添加代码更加方便。 就我而言,您需要在代码部分中指定偏移量,然后将字节复制到正确的位置。 还有一个问题:在内存中寻址。 我向lea命令添加了一个代码,该代码将必要的数据保存在结构中,如果在代码部分中插入新的运算符,则所有偏移量都将对齐,以便它们以新的偏移量指示数据。 好吧,这不是很困难,如果您插入代码,则代码段增加相同的字节数,并且代码段之后的所有其他段将已经包含新的偏移量。 我这样做是为了在粘贴代码的地方有所不同,所有偏移量都能正常工作。 然后出现的问题是

 mov eax, [eax + eax + 0x100] 

事实是,在这种寻址方式中,可以存在ebp并指向堆栈,而不是另一段。 我决定这样做,以便如果地址指向数据部分,则在插入代码时考虑偏移量,如果它指向堆栈,即不是数据部分中的地址,则不要考虑偏移量。

这样,攻击者就可以利用。 毕竟,恶意代码可以插入到程序中某些功能的开头,例如,以便创建fork子代并下载特殊文件。 在Linux中,可以毫无问题地完成此操作。 确实,/ usr / include中包含一个包含操作系统所有系统功能的文件。 也就是说,即使程序没有网络功能,也可以使用网络部分。 我不知道如何在Windows中使用,但是稍后我会尝试添加pe格式的作品。 事实证明它与Linux中的功能相同。 到目前为止,我有一个控制台版本。 但是我打算在gtk上做。

感谢您花时间在我的文章上。

Source: https://habr.com/ru/post/zh-CN477590/


All Articles