linux - 拆卸和重新组装,如何在终端中正确地进行管道传输?

标签 linux assembly nasm reverse-engineering

我正在使用 eicar.com 文件并尝试使用逆向工程工具。我希望能够反汇编和重新组合这个文件。我接近了,但仍有一些问题我无法弄清楚。

这是原文eicar.com ascii 文件。

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

使用 udcli udcli -noff -nohex eicar.com > stage1.asm我最终得到了这个 x86 程序集

pop eax                 
xor eax, 0x2550214f     
inc eax                 
inc ecx                 
push eax                
pop ebx                 
xor al, 0x5c            
push eax                
pop edx                 
pop eax                 
xor eax, 0x5e502834     
sub [edi], esi          
inc ebx                 
inc ebx                 
sub [edi], esi          
jge 0x40                
inc ebp                 
dec ecx                 
inc ebx                 
inc ecx                 
push edx                
sub eax, 0x4e415453     
inc esp                 
inc ecx                 
push edx                
inc esp                 
sub eax, 0x49544e41     
push esi                
dec ecx                 
push edx                
push ebp                
push ebx                
sub eax, 0x54534554     
sub eax, 0x454c4946     
and [eax+ecx*2], esp    
sub ecx, [eax+0x2a]

最后,用nasm把它放回去使用此命令,nasm stage1.asm -o stage2我最终得到...

fXf5O!P%f@fAfPf[4\fPfZfXf54(P^fg)7fCfCfg)7^O<8d>^R^@fEfIfCfAfRf-  STANfDfAfRfDf-ANTIfVfIfRfUfSf-TESTf-FILEfg!$Hfg+H*

在这种情况下,我从一个 ASCII 文件开始,以一个包含大量额外垃圾的 bin 文件结束。

我在这里错过了什么?如何以原始 ASCII 字符串结束并具有正确的文件类型?

编辑: 根据@Ross Ridge 的建议,他注意到我正在将一个 16 位文件反汇编为一个 32 位文件,这已经成功清理了字符串,但是他的文件类型仍然错误地输出为二进制文件。

第一次修复:udcli -16 -noff -nohex eicar.com > stage1.asm以获得正确的输出字符串。

结果 X5O!P%@AP[4\PZX54(P^)7CC)7^O<8d>"^@EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

仍然有一些垃圾数据在原始数据中不存在,但非常接近。

最佳答案

一般来说,您无法将反汇编器的输出重新组装回与原始文件完全相同的二进制文件。通常有不止一种方法可以将给定的汇编指令汇编成机器代码。就你理解代码的最终目标而言,你试图用它来做到这一点也不是很有帮助。即使您确实获得了可以组装回原始代码的东西,您也极不可能获得可以修改并组装成有效代码的东西。

为了说明这一点,我提供了我自己对 eicar.com 文件的“反汇编”,允许对其进行有限程度的修改。您可以修改它打印的字符串,只要消息不是太长并且不包含任何美元符号 $ 字符。假设您只在字符串中放入可打印的 ASCII 字符,您应该能够修改字符串,同时仍然保持仅由可打印的 ASCII 字符组成的输出。

    BITS    16
    ORG     0x100

ascii_shift EQU 0x097b

start:
    pop     ax
    xor     ax, 0x2000 | (skip - start + 0x100) | 0x000f
    push    ax
    and     ax, 0x4000 | (skip - start + 0x100)
    push    ax
    pop     bx
    xor     al, (msg - start) ^ (skip - start)
    push    ax
    pop     dx
    pop     ax
    xor     ax, (0x2000 | (skip - start + 0x100) | 0x000f) ^ ascii_shift
    push    ax
    pop     si
    sub     [bx], si
    inc     bx
    inc     bx
    sub     [bx], si
    jnl     skip

msg:
    DB      'EICAR-STANDARD-ANTIVIRUS-TEST-FILE!'
    DB      '$'

%if ($ - msg) < 0x21
    TIMES   0x21 - ($ - msg) DB '$'
%endif

skip:
    DW      0x21cd + ascii_shift
    DW      0x20cd + ascii_shift

%if skip - msg > 0x7e
%error  'msg too long'
%endif

我不会解释代码是如何工作的,但我会给你一个提示:MS-DOS 在开始执行 .COM 格式的可执行文件时将一个 16 位 0 值压入堆栈。

关于linux - 拆卸和重新组装,如何在终端中正确地进行管道传输?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40921615/

相关文章:

linux - 使用 write syscall linux 的正确方法

mysql - 建立数据库连接时出错

linux - 为 Redis 3.2.6 调整 Linux 内核堆栈

java - Java字节码指令组合对操作数栈的影响

assembly - 为什么我的引导加载程序的堆栈段位于 0x3FF(实模式 IVT 的末尾)?

assembly - 如何在编译时检测 NASM 中的体系结构以获得 x64 和 x86 的一个源代码?

c - 在 Linux 上检测竞争条件的方法有哪些?

Ruby 套接字连接在 0.0.0.0 :8080 上被拒绝

c++ - 如何使用 APM 从保护模式关机?

assembly - 64 位汇编,何时使用较小尺寸的寄存器