Table of Contents
Introduction
In April of 2022 we’ve observed new Emotet samples which implemented considerable changes to the way they store and decode their configuration.
For Emotet, the relevant information stored in a config file is the IP address and a port number. Each of them is stored in the form of a DWORD. Previously, those DWORDs were placed as an encrypted list in the data section of the PE file. It was fairly easy to locate and extract the encrypted blob.
However, with the new changes this is no longer the case. In this blog post we’ll look at the introduced changes and explore an idea of how we can fully statically extract the configuration file.
At the beginning of November 2022 Emotet restarted its spamming campaign after a longer break. The samples being distributed show only minor changes and the approach described in this blog post still applies.
The changes
In the newer version of Emotet, the configuration is no longer stored in an encrypted form in the data section. Instead, each IP and port pair is only obfuscated using data transform obfuscation like encoding literals (Figure 1-a).
When executing the instructions, the final value is produced at runtime. It uses various arithmetic operations and random constants to obfuscate the actual data. However, if we look closely most of it is just junk code. It is fairly easy to extract this via dynamic analysis or emulation.
Of course ‘easy’ is very subjective here. You still need to setup the appropriate context, i.e, correct memory regions, stack alignment and CPU registers might be required. However, if that can be taken care of, you then just have to identify the relevant functions and emulate them. A fully static approach doesn’t require a context, but correct instruction processing is more difficult. Since the data is generated from arithmetic operations, you have to be able to resolve them correctly.
One option is to transform the instruction into another limited set of other instructions. An intermediate representation (IR) for which a series of compiler optimizations could be applied. This has the advantage that the deobfuscation logic can be implemented in a platform independent way.
The IR Idea
We start our investigation by looking at the sample in IDA. Although IDA’s disassembly is very hard to understand since it’s just a bunch of arithmetic and boolean operations, the decompilation of the same function becomes very straightforward to read (Figure 1-b).
This is because while decompiling IDA also uses an IR, which they call microcode. Internally, they use it to perform compiler optimizations. This step eliminates all the dead code, performs constant propagation and various other compiler optimization techniques.
They also have multiple levels of optimizations which one can explore using, e.g., the Lucid plugin. Since it works this well in IDA we are also going to attempt this route.
IR overview
Intermediate Representation (IR) is a representation (an abstract machine language) between the source and the target language. The representation should happen without loss of information. It’s used, e.g., by compilers to perform optimizations that are independent of the target machine. Later, we’ll use this property to extract the configuration data.
For our purpose, we need something that is able to lift a binary without access to source code, is mature, well tested, and actively maintained. We chose VEX, which is the intermediate representation used by the Valgrind framework. It’s also used in the binary analysis framework angr. They also maintain python binding called pyvex. It is able to lift binary code, we don’t lose information and it’s side-effects-free.
Since we’ve chosen VEX we have to understand how it represents instructions. VEX divides the code into code blocks (superblocks, IRSB), which roughly correspond to a basic block. It then translates the instructions to statements (operations with side-effects) and expressions (operations without side-effects).
All the intermediate values are stored in temporary variables called tX, where X is a counter. Each translated block of code starts with an IMark. An IMark is in fact also a statement that just describes the location and length of the corresponding assembly instruction. The documentation can be found in this header file and some examples of such conversions in Table 1.
Assembly
VEX representation
mov [rsp+18h+arg_0], 9A97h
1 | —— IMark(0x400004, 8, 0) ——
2 | t132 = Add64(t0,0x0000000000000020)
3 | STle(t132) = 0x00009a97
4 | PUT(rip) = 0x000000000040000c
mov r8, rcx
1 | —— IMark(0x400014, 3, 0) ——
2 | t1 = GET:I64(rcx)
3 | PUT(r8) = t1
4 | PUT(rip) = 0x0000000000400017
mov [rdx], ecx
1 | —— IMark(0x4000c8, 2, 0) ——
2 | t74 = GET:I64(rdx)
3 | t255 = 64to32(t253)
4 | STle(t74) = t255
5 | PUT(rip) = 0x00000000004000ca
Table 1: Mapping between common assembly operations and VEX IR.
Diving Deeper
Emotet implements the obfuscation of a single IP and port pair inside one unique function which consists of a single basic block with one input and one exit.
We can utilize pyvex to translate each function (basic block) into an intermediate representation which we can then work on. This gives us the advantage that we don’t have to worry too much about the differences between each function and each build of Emotet.
We always work on an IR and not on a complex instruction set. It also allows us to approach this problem in a more generic way. We start our deobfuscation journey by comparing the actual disassembly of an Emotet function, holding the encoded IP and port, with the VEX IR produced by parsing it (Figure 2).
As you might have noticed, the VEX output is very verbose and one assembly instruction corresponds to multiple statements and expressions.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
sub_67B1A8 proc near
var_18= dword ptr -18h
arg_0= dword ptr 8
arg_8= dword ptr 10h
arg_10= dword ptr 18h
arg_18= dword ptr 20h
sub rsp, 18h
mov [rsp+18h+arg_0], 9A97h
mov [rsp+18h+arg_0], 807Eh
mov r8, rcx
add [rsp+18h+arg_0], 0FFFF3193h
add [rsp+18h+arg_0], 6E46h
shr [rsp+18h+arg_0], 4
xor [rsp+18h+arg_0], 0EDF4h
mov eax, [rsp+18h+arg_0]
mov [rsp+18h+arg_0], eax
mov [rsp+18h+arg_10], 2D6320D5h
mov [rsp+18h+var_18], 79899665h
mov [rsp+18h+arg_8], 140067B2h
mov [rsp+18h+arg_18], 66199664h
mov [rsp+18h+arg_0], 41B2h
imul eax, [rsp+18h+arg_0], 1Ah
mov [rsp+18h+arg_0], eax
add [rsp+18h+arg_0], 0FFFF755Ah
imul eax, [rsp+18h+arg_0], 53h
mov [rsp+18h+arg_0], eax
xor [rsp+18h+arg_0], 1FC395Bh
mov eax, [rsp+18h+arg_0]
mov [rsp+18h+arg_0], eax
mov ecx, [rsp+18h+arg_8]
mov eax, [rsp+18h+arg_10]
xor ecx, eax
mov [r8], ecx
mov [rsp+18h+arg_0], 0A161h
xor [rsp+18h+arg_0], 18D37F74h
xor [rsp+18h+arg_0], 18D331E4h
mov eax, [rsp+18h+arg_0]
mov [rsp+18h+arg_0], eax
mov ecx, [rsp+18h+arg_18]
mov eax, [rsp+18h+var_18]
xor ecx, eax
mov eax, 0BA2E8BA3h
mov [rdx], ecx
mov [rsp+18h+arg_0], 0BF0Fh
xor [rsp+18h+arg_0], 59255B83h
mov ecx, [rsp+18h+arg_0]
mul ecx
mov eax, 86186187h
shr edx, 3
mov [rsp+18h+arg_0], edx
mov ecx, [rsp+18h+arg_0]
mul ecx
sub ecx, edx
shr ecx, 1
add ecx, edx
shr ecx, 4
mov [rsp+18h+arg_0], ecx
xor [rsp+18h+arg_0], 62243Ah
mov eax, [rsp+18h+arg_0]
mov [rsp+18h+arg_0], eax
add rsp, 18h
retn
sub_67B1A8 endp
1 ; __int64 __fastcall sub_67B1A8(_DWORD *, _DWORD *)
2 sub_67B1A8 proc near
3
4 var_18= dword ptr -18h
5 arg_0= dword ptr 8
6 arg_8= dword ptr 10h
7 arg_10= dword ptr 18h
8 arg_18= dword ptr 20h
9
10 sub rsp, 18h
11 mov [rsp+18h+arg_0], 9A97h
12 mov [rsp+18h+arg_0], 807Eh
13 mov r8, rcx
14 add [rsp+18h+arg_0], 0FFFF3193h
15 add [rsp+18h+arg_0], 6E46h
16 shr [rsp+18h+arg_0], 4
17 xor [rsp+18h+arg_0], 0EDF4h
18 mov eax, [rsp+18h+arg_0]
19 mov [rsp+18h+arg_0], eax
20 mov [rsp+18h+arg_10], 2D6320D5h
21 mov [rsp+18h+var_18], 79899665h
22 mov [rsp+18h+arg_8], 140067B2h
23 mov [rsp+18h+arg_18], 66199664h
24 mov [rsp+18h+arg_0], 41B2h
25 imul eax, [rsp+18h+arg_0], 1Ah
36 mov [rsp+18h+arg_0], eax
27 add [rsp+18h+arg_0], 0FFFF755Ah
28 imul eax, [rsp+18h+arg_0], 53h
29 mov [rsp+18h+arg_0], eax
30 xor [rsp+18h+arg_0], 1FC395Bh
31 mov eax, [rsp+18h+arg_0]
32 mov [rsp+18h+arg_0], eax
33 mov ecx, [rsp+18h+arg_8]
34 mov eax, [rsp+18h+arg_10]
35 xor ecx, eax
36 mov [r8], ecx
37 mov [rsp+18h+arg_0], 0A161h
38 xor [rsp+18h+arg_0], 18D37F74h
39 xor [rsp+18h+arg_0], 18D331E4h
40 mov eax, [rsp+18h+arg_0]
41 mov [rsp+18h+arg_0], eax
42 mov ecx, [rsp+18h+arg_18]
43 mov eax, [rsp+18h+var_18]
44 xor ecx, eax
45 mov eax, 0BA2E8BA3h
46 mov [rdx], ecx
47 mov [rsp+18h+arg_0], 0BF0Fh
48 xor [rsp+18h+arg_0], 59255B83h
49 mov ecx, [rsp+18h+arg_0]
50 mul ecx
51 mov eax, 86186187h
52 shr edx, 3
53 mov [rsp+18h+arg_0], edx
54 mov ecx, [rsp+18h+arg_0]
55 mul ecx
56 sub ecx, edx
57 shr ecx, 1
58 add ecx, edx
59 shr ecx, 4
60 mov [rsp+18h+arg_0], ecx
61 xor [rsp+18h+arg_0], 62243Ah
62 mov eax, [rsp+18h+arg_0]
63 mov [rsp+18h+arg_0], eax
64 add rsp, 18h
65 retn
66 sub_67B1A8 endp
Figure 2-a: IDA disassembly of an Emotet function
IRSB {
…
00 | —— IMark(0x400000, 4, 0) ——
01 | t2 = GET:I64(rsp)
02 | t0 = Sub64(t2,0x0000000000000018)
03 | PUT(rsp) = t0
04 | PUT(rip) = 0x0000000000400004
05 | —— IMark(0x400004, 8, 0) ——
06 | t132 = Add64(t0,0x0000000000000020)
07 | STle(t132) = 0x00009a97
08 | PUT(rip) = 0x000000000040000c
09 | —— IMark(0x40000c, 8, 0) ——
10 | t134 = Add64(t0,0x0000000000000020)
11 | STle(t134) = 0x0000807e
12 | —— IMark(0x400014, 3, 0) ——
13 | t136 = GET:I64(rcx)
14 | PUT(r8) = t136
15 | PUT(rip) = 0x0000000000400017
16 | —— IMark(0x400017, 8, 0) ——
17 | t137 = Add64(t0,0x0000000000000020)
18 | t7 = LDle:I32(t137)
19 | t5 = Add32(t7,0xffff3193)
20 | STle(t137) = t5
21 | PUT(rip) = 0x000000000040001f
22 | —— IMark(0x40001f, 8, 0) ——
23 | t141 = Add64(t0,0x0000000000000020)
24 | t11 = LDle:I32(t141)
25 | t9 = Add32(t11,0x00006e46)
26 | STle(t141) = t9
27 | PUT(rip) = 0x0000000000400027
28 | —— IMark(0x400027, 5, 0) ——
29 | t145 = Add64(t0,0x0000000000000020)
30 | t13 = LDle:I32(t145)
31 | t147 = 32Uto64(t13)
32 | t17 = Shr64(t147,0x04)
33 | t157 = 64to32(t17)
34 | STle(t145) = t157
35 | PUT(rip) = 0x000000000040002c
…
155 | —— IMark(0x4000b6, 4, 0) ——
156 | t238 = Add64(t0,0x0000000000000020)
157 | t240 = 64to32(t236)
158 | STle(t238) = t240
159 | PUT(rip) = 0x00000000004000ba
160 | —— IMark(0x4000ba, 4, 0) ——
161 | t242 = Add64(t0,0x0000000000000038)
162 | t245 = LDle:I32(t242)
163 | t244 = 32Uto64(t245)
164 | PUT(rip) = 0x00000000004000be
165 | —— IMark(0x4000be, 3, 0) ——
166 | t247 = LDle:I32(t0)
167 | t246 = 32Uto64(t247)
168 | —— IMark(0x4000c1, 2, 0) ——
169 | t248 = 64to32(t244)
170 | t250 = 64to32(t246)
171 | t71 = Xor32(t248,t250)
172 | t253 = 32Uto64(t71)
173 | —— IMark(0x4000c3, 5, 0) ——
174 | PUT(rip) = 0x00000000004000c8
175 | —— IMark(0x4000c8, 2, 0) ——
176 | t74 = GET:I64(rdx)
177 | t255 = 64to32(t253)
178 | STle(t74) = t255
179 | PUT(rip) = 0x00000000004000ca
180 | —— IMark(0x4000ca, 8, 0) ——
181 | t257 = Add64(t0,0x0000000000000020)
182 | STle(t257) = 0x0000bf0f
183 | PUT(rip) = 0x00000000004000d2
184 | —— IMark(0x4000d2, 8, 0) ——
185 | t259 = Add64(t0,0x0000000000000020)
186 | t78 = LDle:I32(t259)
187 | t76 = Xor32(t78,0x59255b83)
188 | STle(t259) = t76
189 | PUT(rip) = 0x00000000004000da
…
263 | —— IMark(0x40010b, 4, 0) ——
264 | t362 = Add64(t0,0x0000000000000020)
265 | t364 = 64to32(t360)
266 | STle(t362) = t364
267 | —— IMark(0x40010f, 4, 0) ——
268 | t129 = Add64(t0,0x0000000000000018)
269 | PUT(cc_op) = 0x0000000000000004
270 | PUT(cc_dep1) = t0
271 | PUT(cc_dep2) = 0x0000000000000018
272 | PUT(rsp) = t129
NEXT: PUT(rip) = 0x0000000000400113; Ijk_Boring
}
Figure 2-b: the IR representation
By first analyzing the disassembled function, we can identify certain points of interest. For example, since this is a 64-bit code, we know that according to the Microsoft x64 calling convention the arguments are passed in RCX, RDX, R8, and R9 registers. The function responsible for deobfuscating the IP and port takes two arguments which means the first two are used to pass parameters.
We also notice that final, deobfuscated values are being written to the memory locations that the function arguments point to (Figure 3). So the arguments are pointers and the data that we are interested in is being written to these locations. This is once again confirmed by looking at the output produced by IDA’s decompiler.
If we investigate other functions which also encode the IP and port DWORDs, we realize that the decoded values are always stored at the location the arguments are pointing to. This should be our starting point when analyzing the IRSB block.
The following x64 instructions, which move ECX into the 8 bytes at memory location R8/RDX:
- mov [r8], ecx
- mov [rdx], ecx
translate into a get expression and a store statement (Table 1). Such memory moves are our candidates that should hold the final values. We can iterate over the IRSB block looking for a combination of get followed by a store. An example of that can be found in line 176 and 178 (Figure 2-b).
However, that’s only the first step. If we look at the IR at line 178, where the store operation that we are interested in is performed, we notice that a temporary register is used (t255). This register was assigned at line 177 and its source was the register t253. The assignment to register t253 was done on line 172 and the source for that is t71. This goes on and on. Since we are interested in the final value assigned to the memory locations passed in as arguments, we need to find the starting point and do the necessary calculations ourselves.
At this point it’s worth noting that the currently distributed samples made some minor adjustments. Instead of two arguments, the decoding function now takes only one. This is a pointer to a structure with two DWORD elements. The only thing that changes in the approach described above is that we need to additionally find a memory write to a location shifted by 4 bytes (Figure 4).
The overall approach could be the following:
First, we can perform a sweep and create a mapping of registers that we are interested in. Those registers should be the ones related to our output value. Some of those might be the result of certain arithmetic operations as can be seen in line 171. So in addition to the registers of interest we also need to track those operations and which registers are being used as input there. In some other cases, the value is loaded from the stack or from another register that holds the stack pointer (line 166) and we need to track those loads and stack locations too.
The approach can be summarized by the following steps:
- Create a mapping between temporary registers
- If a register is the result of a binary or unary operation on other register(s), add the operation and the registers to the mapping
- If a register is assigned a value from memory, add the load and the location to the mapping
After we’ve collected the necessary information and created the mapping we can start reconstructing the values. We need to resolve the registers, propagate all values and perform necessary arithmetic operations.
In the following, we present an example of a manual reconstruction of values for the function in Appendix A. The example is presented in the form of a graph where all intermediate registers and operations are converted to nodes. We then eliminate all intermediate nodes that don’t change the actual value greatly simplifying the representation (Figure 5):
In the graph form, all registers are marked blue and operations green. The random constants that are loaded from the stack are marked as white. We start with register t74. The location that the value in that register points to is being written to in line 178 (Figure 2-b). From the graph, we know that registers t255 and t71 don’t make any changes and we can safely eliminate them. We can apply the same rule to the other registers in the graph, removing most of the blue nodes.
We also know that behind the Load operations are constant values placed on the stack, so we can eliminate them too after retrieving the constant. That leaves us with a reduced graph seen on the right-hand side. What’s left is to perform the XOR operation on the two constant values. After that we are presented with the final value encoding the port number and a flag (0x1F900001).
By applying the same approach to the other value (IP address) we are able to reduce it to just the final value in the same manner that IDA’s decompiler is doing it. What’s left at this point is to extract all other functions which are obfuscating the C2 information and apply the steps discussed above. We’ve used this method to extract all C2 addresses (Figure 6) that Emotet uses as can be seen in this report.
Conclusions
As we have seen, it’s possible to extract Emotet’s configuration statically and in a generic way by utilizing an approach similar to what compilers use. This has the advantage that
- our algorithms can be abstracted away from the very complex instruction set and
- are more robust to changes in the underlying obfuscation.
This method can also be applied to other malware families that utilize similar obfuscation techniques.
The Malware Configuration Extraction feature of VMRay Analyzer is able to automatically extract relevant C2 information from Emotet samples and present them as actionable IOCs in the report.
Mateusz is a Threat Researcher at VMRay Labs. His recent projects cover in-depth analysis of emerging and evolving malware.
References
Appendix A:
IOCs
Initial DLL
SHA256
d5415fac6b6576702e52afae605748b6e5a72a920bf381f365d35b3411aa9fbf
19fcf233637e0ca65c4eef3b234d3c79ad1604b524da1b1f292cf7e7dcaf13aa
Payload
SHA256:
dc0489d026530618569f6fd4e082401b1c3d31c7aaad3685ebea0454fc15be12
Appendix B:
IRSB {
t0:Ity_I64 t1:Ity_I64 t2:Ity_I64 t3:Ity_I64 t4:Ity_I64 t5:Ity_I32 t6:Ity_I32 t7:Ity_I32 t8:Ity_I64 t9:Ity_I32 t10:Ity_I32 t11:Ity_I32 t12:Ity_I64 t13:Ity_I32 t14:Ity_I32 t15:Ity_I64 t16:Ity_I64 t17:Ity_I64 t18:Ity_I64 t19:Ity_I8 t20:Ity_I1 t21:Ity_I32 t22:Ity_I32 t23:Ity_I32 t24:Ity_I64 t25:Ity_I64 t26:Ity_I64 t27:Ity_I64 t28:Ity_I64 t29:Ity_I64 t30:Ity_I64 t31:Ity_I64 t32:Ity_I32 t33:Ity_I32 t34:Ity_I32 t35:Ity_I64 t36:Ity_I64 t37:Ity_I32 t38:Ity_I32 t39:Ity_I32 t40:Ity_I64 t41:Ity_I32 t42:Ity_I32 t43:Ity_I32 t44:Ity_I64 t45:Ity_I64 t46:Ity_I32 t47:Ity_I32 t48:Ity_I32 t49:Ity_I64 t50:Ity_I64 t51:Ity_I64 t52:Ity_I64 t53:Ity_I64 t54:Ity_I32 t55:Ity_I32 t56:Ity_I32 t57:Ity_I64 t58:Ity_I64 t59:Ity_I32 t60:Ity_I32 t61:Ity_I32 t62:Ity_I64 t63:Ity_I32 t64:Ity_I32 t65:Ity_I32 t66:Ity_I64 t67:Ity_I64 t68:Ity_I64 t69:Ity_I64 t70:Ity_I64 t71:Ity_I32 t72:Ity_I32 t73:Ity_I32 t74:Ity_I64 t75:Ity_I64 t76:Ity_I32 t77:Ity_I32 t78:Ity_I32 t79:Ity_I64 t80:Ity_I64 t81:Ity_I32 t82:Ity_I32 t83:Ity_I32 t84:Ity_I64 t85:Ity_I32 t86:Ity_I32 t87:Ity_I32 t88:Ity_I32 t89:Ity_I64 t90:Ity_I64 t91:Ity_I64 t92:Ity_I8 t93:Ity_I1 t94:Ity_I64 t95:Ity_I64 t96:Ity_I32 t97:Ity_I32 t98:Ity_I32 t99:Ity_I64 t100:Ity_I32 t101:Ity_I32 t102:Ity_I32 t103:Ity_I32 t104:Ity_I32 t105:Ity_I32 t106:Ity_I32 t107:Ity_I64 t108:Ity_I64 t109:Ity_I64 t110:Ity_I8 t111:Ity_I1 t112:Ity_I32 t113:Ity_I32 t114:Ity_I32 t115:Ity_I32 t116:Ity_I32 t117:Ity_I64 t118:Ity_I64 t119:Ity_I64 t120:Ity_I8 t121:Ity_I1 t122:Ity_I64 t123:Ity_I32 t124:Ity_I32 t125:Ity_I32 t126:Ity_I64 t127:Ity_I64 t128:Ity_I64 t129:Ity_I64 t130:Ity_I64 t131:Ity_I64 t132:Ity_I64 t133:Ity_I64 t134:Ity_I64 t135:Ity_I64 t136:Ity_I64 t137:Ity_I64 t138:Ity_I64 t139:Ity_I64 t140:Ity_I64 t141:Ity_I64 t142:Ity_I64 t143:Ity_I64 t144:Ity_I64 t145:Ity_I64 t146:Ity_I64 t147:Ity_I64 t148:Ity_I64 t149:Ity_I8 t150:Ity_I8 t151:Ity_I64 t152:Ity_I64 t153:Ity_I64 t154:Ity_I64 t155:Ity_I64 t156:Ity_I64 t157:Ity_I32 t158:Ity_I64 t159:Ity_I64 t160:Ity_I64 t161:Ity_I64 t162:Ity_I64 t163:Ity_I64 t164:Ity_I32 t165:Ity_I64 t166:Ity_I64 t167:Ity_I32 t168:Ity_I64 t169:Ity_I64 t170:Ity_I64 t171:Ity_I64 t172:Ity_I64 t173:Ity_I64 t174:Ity_I64 t175:Ity_I64 t176:Ity_I64 t177:Ity_I64 t178:Ity_I64 t179:Ity_I64 t180:Ity_I64 t181:Ity_I64 t182:Ity_I64 t183:Ity_I64 t184:Ity_I32 t185:Ity_I64 t186:Ity_I64 t187:Ity_I64 t188:Ity_I64 t189:Ity_I64 t190:Ity_I64 t191:Ity_I64 t192:Ity_I64 t193:Ity_I64 t194:Ity_I64 t195:Ity_I64 t196:Ity_I64 t197:Ity_I32 t198:Ity_I64 t199:Ity_I64 t200:Ity_I64 t201:Ity_I64 t202:Ity_I64 t203:Ity_I64 t204:Ity_I64 t205:Ity_I32 t206:Ity_I64 t207:Ity_I64 t208:Ity_I32 t209:Ity_I64 t210:Ity_I64 t211:Ity_I64 t212:Ity_I64 t213:Ity_I32 t214:Ity_I64 t215:Ity_I64 t216:Ity_I64 t217:Ity_I32 t218:Ity_I32 t219:Ity_I64 t220:Ity_I32 t221:Ity_I64 t222:Ity_I64 t223:Ity_I64 t224:Ity_I32 t225:Ity_I64 t226:Ity_I64 t227:Ity_I64 t228:Ity_I64 t229:Ity_I64 t230:Ity_I64 t231:Ity_I64 t232:Ity_I64 t233:Ity_I64 t234:Ity_I64 t235:Ity_I64 t236:Ity_I64 t237:Ity_I32 t238:Ity_I64 t239:Ity_I64 t240:Ity_I32 t241:Ity_I64 t242:Ity_I64 t243:Ity_I64 t244:Ity_I64 t245:Ity_I32 t246:Ity_I64 t247:Ity_I32 t248:Ity_I32 t249:Ity_I64 t250:Ity_I32 t251:Ity_I64 t252:Ity_I64 t253:Ity_I64 t254:Ity_I64 t255:Ity_I32 t256:Ity_I64 t257:Ity_I64 t258:Ity_I64 t259:Ity_I64 t260:Ity_I64 t261:Ity_I64 t262:Ity_I64 t263:Ity_I64 t264:Ity_I64 t265:Ity_I32 t266:Ity_I32 t267:Ity_I64 t268:Ity_I32 t269:Ity_I64 t270:Ity_I64 t271:Ity_I64 t272:Ity_I32 t273:Ity_I32 t274:Ity_I64 t275:Ity_I64 t276:Ity_I64 t277:Ity_I32 t278:Ity_I64 t279:Ity_I64 t280:Ity_I64 t281:Ity_I8 t282:Ity_I8 t283:Ity_I64 t284:Ity_I64 t285:Ity_I64 t286:Ity_I64 t287:Ity_I64 t288:Ity_I64 t289:Ity_I32 t290:Ity_I64 t291:Ity_I64 t292:Ity_I64 t293:Ity_I32 t294:Ity_I64 t295:Ity_I64 t296:Ity_I64 t297:Ity_I64 t298:Ity_I32 t299:Ity_I32 t300:Ity_I64 t301:Ity_I32 t302:Ity_I64 t303:Ity_I64 t304:Ity_I64 t305:Ity_I32 t306:Ity_I32 t307:Ity_I64 t308:Ity_I64 t309:Ity_I32 t310:Ity_I64 t311:Ity_I32 t312:Ity_I64 t313:Ity_I64 t314:Ity_I64 t315:Ity_I64 t316:Ity_I32 t317:Ity_I64 t318:Ity_I64 t319:Ity_I64 t320:Ity_I8 t321:Ity_I8 t322:Ity_I64 t323:Ity_I64 t324:Ity_I64 t325:Ity_I64 t326:Ity_I64 t327:Ity_I64 t328:Ity_I32 t329:Ity_I64 t330:Ity_I32 t331:Ity_I64 t332:Ity_I32 t333:Ity_I64 t334:Ity_I64 t335:Ity_I64 t336:Ity_I64 t337:Ity_I32 t338:Ity_I64 t339:Ity_I64 t340:Ity_I64 t341:Ity_I8 t342:Ity_I8 t343:Ity_I64 t344:Ity_I64 t345:Ity_I64 t346:Ity_I64 t347:Ity_I64 t348:Ity_I64 t349:Ity_I32 t350:Ity_I64 t351:Ity_I64 t352:Ity_I64 t353:Ity_I32 t354:Ity_I64 t355:Ity_I64 t356:Ity_I64 t357:Ity_I64 t358:Ity_I64 t359:Ity_I64 t360:Ity_I64 t361:Ity_I32 t362:Ity_I64 t363:Ity_I64 t364:Ity_I32 t365:Ity_I64 t366:Ity_I64
00 | —— IMark(0x400000, 4, 0) ——
01 | t2 = GET:I64(rsp)
02 | t0 = Sub64(t2,0x0000000000000018)
03 | PUT(rsp) = t0
04 | PUT(rip) = 0x0000000000400004
05 | —— IMark(0x400004, 8, 0) ——
06 | t132 = Add64(t0,0x0000000000000020)
07 | STle(t132) = 0x00009a97
08 | PUT(rip) = 0x000000000040000c
09 | —— IMark(0x40000c, 8, 0) ——
10 | t134 = Add64(t0,0x0000000000000020)
11 | STle(t134) = 0x0000807e
12 | —— IMark(0x400014, 3, 0) ——
13 | t136 = GET:I64(rcx)
14 | PUT(r8) = t136
15 | PUT(rip) = 0x0000000000400017
16 | —— IMark(0x400017, 8, 0) ——
17 | t137 = Add64(t0,0x0000000000000020)
18 | t7 = LDle:I32(t137)
19 | t5 = Add32(t7,0xffff3193)
20 | STle(t137) = t5
21 | PUT(rip) = 0x000000000040001f
22 | —— IMark(0x40001f, 8, 0) ——
23 | t141 = Add64(t0,0x0000000000000020)
24 | t11 = LDle:I32(t141)
25 | t9 = Add32(t11,0x00006e46)
26 | STle(t141) = t9
27 | PUT(rip) = 0x0000000000400027
28 | —— IMark(0x400027, 5, 0) ——
29 | t145 = Add64(t0,0x0000000000000020)
30 | t13 = LDle:I32(t145)
31 | t147 = 32Uto64(t13)
32 | t17 = Shr64(t147,0x04)
33 | t157 = 64to32(t17)
34 | STle(t145) = t157
35 | PUT(rip) = 0x000000000040002c
36 | —— IMark(0x40002c, 8, 0) ——
37 | t158 = Add64(t0,0x0000000000000020)
38 | t23 = LDle:I32(t158)
39 | t21 = Xor32(t23,0x0000edf4)
40 | STle(t158) = t21
41 | PUT(rip) = 0x0000000000400034
42 | —— IMark(0x400034, 4, 0) ——
43 | t161 = Add64(t0,0x0000000000000020)
44 | t164 = LDle:I32(t161)
45 | t163 = 32Uto64(t164)
46 | PUT(rip) = 0x0000000000400038
47 | —— IMark(0x400038, 4, 0) ——
48 | t165 = Add64(t0,0x0000000000000020)
49 | t167 = 64to32(t163)
50 | STle(t165) = t167
51 | PUT(rip) = 0x000000000040003c
52 | —— IMark(0x40003c, 8, 0) ——
53 | t169 = Add64(t0,0x0000000000000030)
54 | STle(t169) = 0x2d6320d5
55 | PUT(rip) = 0x0000000000400044
56 | —— IMark(0x400044, 7, 0) ——
57 | STle(t0) = 0x79899665
58 | PUT(rip) = 0x000000000040004b
59 | —— IMark(0x40004b, 8, 0) ——
60 | t171 = Add64(t0,0x0000000000000028)
61 | STle(t171) = 0x140067b2
62 | PUT(rip) = 0x0000000000400053
63 | —— IMark(0x400053, 8, 0) ——
64 | t173 = Add64(t0,0x0000000000000038)
65 | STle(t173) = 0x66199664
66 | PUT(rip) = 0x000000000040005b
67 | —— IMark(0x40005b, 8, 0) ——
68 | t175 = Add64(t0,0x0000000000000020)
69 | STle(t175) = 0x000041b2
70 | PUT(rip) = 0x0000000000400063
71 | —— IMark(0x400063, 5, 0) ——
72 | t177 = Add64(t0,0x0000000000000020)
73 | t32 = LDle:I32(t177)
74 | t34 = Mul32(t32,0x0000001a)
75 | t181 = 32Uto64(t34)
76 | PUT(rip) = 0x0000000000400068
77 | —— IMark(0x400068, 4, 0) ——
78 | t182 = Add64(t0,0x0000000000000020)
79 | t184 = 64to32(t181)
80 | STle(t182) = t184
81 | PUT(rip) = 0x000000000040006c
82 | —— IMark(0x40006c, 8, 0) ——
83 | t186 = Add64(t0,0x0000000000000020)
84 | t39 = LDle:I32(t186)
85 | t37 = Add32(t39,0xffff755a)
86 | STle(t186) = t37
87 | PUT(rip) = 0x0000000000400074
88 | —— IMark(0x400074, 5, 0) ——
89 | t190 = Add64(t0,0x0000000000000020)
90 | t41 = LDle:I32(t190)
91 | t43 = Mul32(t41,0x00000053)
92 | t194 = 32Uto64(t43)
93 | PUT(rip) = 0x0000000000400079
94 | —— IMark(0x400079, 4, 0) ——
95 | t195 = Add64(t0,0x0000000000000020)
96 | t197 = 64to32(t194)
97 | STle(t195) = t197
98 | PUT(rip) = 0x000000000040007d
99 | —— IMark(0x40007d, 8, 0) ——
100 | t199 = Add64(t0,0x0000000000000020)
101 | t48 = LDle:I32(t199)
102 | t46 = Xor32(t48,0x01fc395b)
103 | STle(t199) = t46
104 | PUT(rip) = 0x0000000000400085
105 | —— IMark(0x400085, 4, 0) ——
106 | t202 = Add64(t0,0x0000000000000020)
107 | t205 = LDle:I32(t202)
108 | t204 = 32Uto64(t205)
109 | PUT(rip) = 0x0000000000400089
110 | —— IMark(0x400089, 4, 0) ——
111 | t206 = Add64(t0,0x0000000000000020)
112 | t208 = 64to32(t204)
113 | STle(t206) = t208
114 | PUT(rip) = 0x000000000040008d
115 | —— IMark(0x40008d, 4, 0) ——
116 | t210 = Add64(t0,0x0000000000000028)
117 | t213 = LDle:I32(t210)
118 | t212 = 32Uto64(t213)
119 | PUT(rip) = 0x0000000000400091
120 | —— IMark(0x400091, 4, 0) ——
121 | t214 = Add64(t0,0x0000000000000030)
122 | t217 = LDle:I32(t214)
123 | t216 = 32Uto64(t217)
124 | —— IMark(0x400095, 2, 0) ——
125 | t218 = 64to32(t212)
126 | t220 = 64to32(t216)
127 | t54 = Xor32(t218,t220)
128 | t223 = 32Uto64(t54)
129 | PUT(rip) = 0x0000000000400097
130 | —— IMark(0x400097, 3, 0) ——
131 | t224 = 64to32(t223)
132 | STle(t136) = t224
133 | PUT(rip) = 0x000000000040009a
134 | —— IMark(0x40009a, 8, 0) ——
135 | t226 = Add64(t0,0x0000000000000020)
136 | STle(t226) = 0x0000a161
137 | PUT(rip) = 0x00000000004000a2
138 | —— IMark(0x4000a2, 8, 0) ——
139 | t228 = Add64(t0,0x0000000000000020)
140 | t61 = LDle:I32(t228)
141 | t59 = Xor32(t61,0x18d37f74)
142 | STle(t228) = t59
143 | PUT(rip) = 0x00000000004000aa
144 | —— IMark(0x4000aa, 8, 0) ——
145 | t231 = Add64(t0,0x0000000000000020)
146 | t65 = LDle:I32(t231)
147 | t63 = Xor32(t65,0x18d331e4)
148 | STle(t231) = t63
149 | PUT(rip) = 0x00000000004000b2
150 | —— IMark(0x4000b2, 4, 0) ——
151 | t234 = Add64(t0,0x0000000000000020)
152 | t237 = LDle:I32(t234)
153 | t236 = 32Uto64(t237)
154 | PUT(rip) = 0x00000000004000b6
155 | —— IMark(0x4000b6, 4, 0) ——
156 | t238 = Add64(t0,0x0000000000000020)
157 | t240 = 64to32(t236)
158 | STle(t238) = t240
159 | PUT(rip) = 0x00000000004000ba
160 | —— IMark(0x4000ba, 4, 0) ——
161 | t242 = Add64(t0,0x0000000000000038)
162 | t245 = LDle:I32(t242)
163 | t244 = 32Uto64(t245)
164 | PUT(rip) = 0x00000000004000be
165 | —— IMark(0x4000be, 3, 0) ——
166 | t247 = LDle:I32(t0)
167 | t246 = 32Uto64(t247)
168 | —— IMark(0x4000c1, 2, 0) ——
169 | t248 = 64to32(t244)
170 | t250 = 64to32(t246)
171 | t71 = Xor32(t248,t250)
172 | t253 = 32Uto64(t71)
173 | —— IMark(0x4000c3, 5, 0) ——
174 | PUT(rip) = 0x00000000004000c8
175 | —— IMark(0x4000c8, 2, 0) ——
176 | t74 = GET:I64(rdx)
177 | t255 = 64to32(t253)
178 | STle(t74) = t255
179 | PUT(rip) = 0x00000000004000ca
180 | —— IMark(0x4000ca, 8, 0) ——
181 | t257 = Add64(t0,0x0000000000000020)
182 | STle(t257) = 0x0000bf0f
183 | PUT(rip) = 0x00000000004000d2
184 | —— IMark(0x4000d2, 8, 0) ——
185 | t259 = Add64(t0,0x0000000000000020)
186 | t78 = LDle:I32(t259)
187 | t76 = Xor32(t78,0x59255b83)
188 | STle(t259) = t76
189 | PUT(rip) = 0x00000000004000da
190 | —— IMark(0x4000da, 4, 0) ——
191 | t262 = Add64(t0,0x0000000000000020)
192 | t265 = LDle:I32(t262)
193 | t264 = 32Uto64(t265)
194 | —— IMark(0x4000de, 2, 0) ——
195 | t266 = 64to32(t264)
196 | t84 = MullU32(0xba2e8ba3,t266)
197 | t272 = 64HIto32(t84)
198 | t274 = 32Uto64(t272)
199 | —— IMark(0x4000e0, 5, 0) ——
200 | —— IMark(0x4000e5, 3, 0) ——
201 | t277 = 64to32(t274)
202 | t279 = 32Uto64(t277)
203 | t90 = Shr64(t279,0x03)
204 | t289 = 64to32(t90)
205 | t290 = 32Uto64(t289)
206 | PUT(rip) = 0x00000000004000e8
207 | —— IMark(0x4000e8, 4, 0) ——
208 | t291 = Add64(t0,0x0000000000000020)
209 | t293 = 64to32(t290)
210 | STle(t291) = t293
211 | PUT(rip) = 0x00000000004000ec
212 | —— IMark(0x4000ec, 4, 0) ——
213 | t295 = Add64(t0,0x0000000000000020)
214 | t298 = LDle:I32(t295)
215 | t297 = 32Uto64(t298)
216 | —— IMark(0x4000f0, 2, 0) ——
217 | t299 = 64to32(t297)
218 | t99 = MullU32(0x86186187,t299)
219 | t305 = 64HIto32(t99)
220 | t307 = 32Uto64(t305)
221 | PUT(rdx) = t307
222 | —— IMark(0x4000f2, 2, 0) ——
223 | t309 = 64to32(t297)
224 | t311 = 64to32(t307)
225 | t102 = Sub32(t309,t311)
226 | t315 = 32Uto64(t102)
227 | —— IMark(0x4000f4, 2, 0) ——
228 | t316 = 64to32(t315)
229 | t318 = 32Uto64(t316)
230 | t108 = Shr64(t318,0x01)
231 | t328 = 64to32(t108)
232 | t329 = 32Uto64(t328)
233 | —— IMark(0x4000f6, 2, 0) ——
234 | t330 = 64to32(t329)
235 | t332 = 64to32(t307)
236 | t112 = Add32(t330,t332)
237 | t336 = 32Uto64(t112)
238 | —— IMark(0x4000f8, 3, 0) ——
239 | t337 = 64to32(t336)
240 | t339 = 32Uto64(t337)
241 | t118 = Shr64(t339,0x04)
242 | t349 = 64to32(t118)
243 | t350 = 32Uto64(t349)
244 | PUT(rcx) = t350
245 | PUT(rip) = 0x00000000004000fb
246 | —— IMark(0x4000fb, 4, 0) ——
247 | t351 = Add64(t0,0x0000000000000020)
248 | t353 = 64to32(t350)
249 | STle(t351) = t353
250 | PUT(rip) = 0x00000000004000ff
251 | —— IMark(0x4000ff, 8, 0) ——
252 | t355 = Add64(t0,0x0000000000000020)
253 | t125 = LDle:I32(t355)
254 | t123 = Xor32(t125,0x0062243a)
255 | STle(t355) = t123
256 | PUT(rip) = 0x0000000000400107
257 | —— IMark(0x400107, 4, 0) ——
258 | t358 = Add64(t0,0x0000000000000020)
259 | t361 = LDle:I32(t358)
260 | t360 = 32Uto64(t361)
261 | PUT(rax) = t360
262 | PUT(rip) = 0x000000000040010b
263 | —— IMark(0x40010b, 4, 0) ——
264 | t362 = Add64(t0,0x0000000000000020)
265 | t364 = 64to32(t360)
266 | STle(t362) = t364
267 | —— IMark(0x40010f, 4, 0) ——
268 | t129 = Add64(t0,0x0000000000000018)
269 | PUT(cc_op) = 0x0000000000000004
270 | PUT(cc_dep1) = t0
271 | PUT(cc_dep2) = 0x0000000000000018
272 | PUT(rsp) = t129
NEXT: PUT(rip) = 0x0000000000400113; Ijk_Boring
}
Subscribe
Stay current on the threat landscape with industry-leading insights.