我正在尝试应对挑战。尝试挑战#3时遇到了麻烦,无法解决。在研究了由其他人编写的解决方案之后,我现在确实知道该程序的工作原理,但是我在下面的一行中感到困惑。

该指令将地址移入ecx寄存器,并与eax寄存器结合使用以替换同一位置的某些值。这样做的循环是:

mov     ecx, offset loc_40107C
add     ecx, 79h
mov     eax, offset loc_40107C
mov     dl, [ebp+buf]


但是当我尝试输入位置40107C时,该位置似乎具有以下指示:



因为该位置用于存储值,所以该位置不可以为空或具有除汇编指令之外的其他值,或者我在这里误解了某些东西,有人可以澄清吗? />我正在阅读的解决方案:https://www.fireeye.com/content/dam/fireeye-www/global/zh/blog/threat-research/Flare-On%202017/Challenge%20%233%20solution。 pdf

评论

反汇编将导致这样的代码buf [i] =(buf [i] ^(char *)0x40107c [i])+ 0x22

#1 楼


位置不应该为空或除汇编指令以外是否具有其他值...?


答案为“否”。正如作者在本文中所述,此二进制文件是可自我修改的:到达0x401101
...
样本的PE标头中找到了另一种自我修改代码的指示。 。


任何尝试将.text0x40107C的字节反汇编都将导致错误且无意义的汇编指令。因此,我们应该了解操纵此字节的功能。

了解修改功能

您已经注意到,这是负责修改此范围内字节的代码:

loc_401039:
mov     bl, [eax]
xor     bl, dl
add     bl, 22h
mov     [eax], bl
inc     eax
cmp     eax, ecx
jl      short loc_401039


让我们使用伪代码来理解它的工作原理: 0x40107C+0x79被添加到结果中。


演示

扰流板警报!下一部分包含与答案有关的扰流板

写-附件中包含一个解决方案,该解决方案用于XOR操作中修改字节的右键。我将在以下示例中使用此键。

键是(悬停以查看它):


0xa2


让我们尝试自己解密这些字节。我将使用radare2,但您可以使用任何其他想要的解决方案。

首先,让我们来复制此挑战,因为我们将要编辑二进制文件:

start_addr = 0x0x40107c
end_addr = 0x40107c + 0x79 = 0x4010f5
key = 0x??

for addr in range(start_addr, end_addr+1):
    # setByte (address, new_value); getByte (address)
    setByte(addr, (getByte(addr)^key)+0x22)


现在在写模式下使用radare2打开二进制文件:看起来像在我们修改那里的字节之前一样:

$ cp greek_to_me.exe modified_greek_to_me.exe


我在此地址打印了10个操作码。如您所见,这些指令没有意义,因为在当前状态下,它们不应该被反汇编。 >
$ r2 -w modified_greek_to_me.exe
[0x00401000]>


现在我们要对0x22中的0x40107c字节进行异或,然后将0x79添加到每个字节中。我们可以使用radare2轻松地实现它。

首先,我们应该定义要处理的块大小,在本例中为0x79: br />在radare2命令中添加0x79将显示有关该命令及其子命令的帮助

现在,让我们对0x40107c0x22的字节进行XOR,然后将?添加到其中的每个字节: br />
[0x00401000]> s 0x40107c
[0x0040107c]> pd 10
            0x0040107c      33e1           xor esp, ecx
            0x0040107e      c49911068116   les ebx, [ecx + 0x16810611]
            0x00401084      f0             invalid
            0x00401085      329fc4911706   xor bl, byte [edi + 0x61791c4]
            0x0040108b      8114f0068115.  adc dword [eax + esi*8], 0xf1158106
            0x00401092      c4911a06811b   les edx, [ecx + 0x1b81061a]
        ╭─< 0x00401098      e206           loop 0x4010a0
        │   0x0040109a      8118f2068119   sbb dword [eax], 0x198106f2
        ╰─> 0x004010a0      f1             int1
            0x004010a1      06             push es


现在我们的字节被修改了。让我们看看它们在十六进制模式下的样子:
[0x0040107c]> px 0x79
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x0040107c  33e1 c499 1106 8116 f032 9fc4 9117 0681  3........2......
0x0040108c  14f0 0681 15f1 c491 1a06 811b e206 8118  ................
0x0040109c  f206 8119 f106 811e f0c4 991f c491 1c06  ................
0x004010ac  811d e606 8162 ef06 8163 f206 8160 e3c4  .....b...c...`..
0x004010bc  9961 0681 66bc 0681 67e6 0681 64e8 0681  .a..f...g...d...
0x004010cc  659d 0681 6af2 c499 6b06 8168 a906 8169  e...j...k..h...i
0x004010dc  ef06 816e ee06 816f ae06 816c e306 816d  ...n...o.


确实,现在我们可以看到所有构建该标志的0x40107c指令:)

#2 楼

从上面的代码ecx存储缓冲区末尾的地址(loc_40107C + 0x79)。 eax指向开始处,然后通过将eaxeax进行比较来检查ecx是否已到达缓冲区的末尾。在循环中修改。您粘贴的代码应被视为数据,因此应被视为0x40107C

现在,在0xF1, 0x06, 0x81, 0x1e, 0xf0, 0xc4, 0x99, 0x1f...下存在一些内容,当在此缓冲区上使用并添加[ebp+buf]时,会得到一些有意义的代码。