首页 A Try on Reverse Engineering | Vincent's Technical Reports (Vol. 1)
文章
取消

A Try on Reverse Engineering | Vincent's Technical Reports (Vol. 1)

一次有趣的逆向工程经历

前因

在五道口技术学院某抽象院系的某课程的一次作业中,出现了有趣的情况。

作业要求监测某可执行文件运行过程中的数据,再用数据推测得到助教提前设置好的两个信息。

提供给同学们下载的是编译好的可执行文件,而不是源代码,不然可以直接阅读源码获得答案。

同时,这个可执行文件运行需要一个参数,助教规定每个同学将参数设置为自己的学号。

这是为了保证同学们的答案不全相同来防止抄袭,但也可以推测出正确答案是输入参数的某个函数。

使用objdump进行反汇编

1
2
3
4
5
// -d 选项指示 objdump 对目标文件中包含可执行代码的节(section)进行反汇编
// 将机器码转换为对应架构的汇编指令。 
// -C 选项用于解析编译器对符号名进行的名称修饰(name mangling)
// 将修饰后的符号名转换为原始可读的函数名,如 foo(int, int)/lipsum()
objdump -d -C ./main

执行命令后得到本次所关注的lipsum()函数和main函数。

1
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
0000000000001150 <main>:
    1150:       41 54                   push   %r12
    1152:       55                      push   %rbp
    1153:       48 83 ec 18             sub    $0x18,%rsp
    1157:       89 7c 24 0c             mov    %edi,0xc(%rsp)
    115b:       48 8d 7c 24 0c          lea    0xc(%rsp),%rdi
    1160:       48 89 34 24             mov    %rsi,(%rsp)
    1164:       48 89 e6                mov    %rsp,%rsi
    1167:       e8 94 ff ff ff          call   1100 <MPI_Init@plt>
    116c:       48 8d 35 91 5e d4 41    lea    0x41d45e91(%rip),%rsi        # 41d47004 <mpiSize>
    1173:       bf 00 00 00 44          mov    $0x44000000,%edi
    1178:       e8 33 ff ff ff          call   10b0 <MPI_Comm_size@plt>
    117d:       48 8d 35 84 5e d4 41    lea    0x41d45e84(%rip),%rsi        # 41d47008 <mpiRank>
    1184:       bf 00 00 00 44          mov    $0x44000000,%edi
    1189:       e8 62 ff ff ff          call   10f0 <MPI_Comm_rank@plt>
    118e:       83 3d 6f 5e d4 41 08    cmpl   $0x8,0x41d45e6f(%rip)        # 41d47004 <mpiSize>
    1195:       0f 85 83 01 00 00       jne    131e <main+0x1ce>
    119b:       83 7c 24 0c 02          cmpl   $0x2,0xc(%rsp)
    11a0:       0f 85 56 01 00 00       jne    12fc <main+0x1ac>
    11a6:       48 8b 04 24             mov    (%rsp),%rax
    11aa:       31 f6                   xor    %esi,%esi
    11ac:       ba 0a 00 00 00          mov    $0xa,%edx
    11b1:       48 8b 78 08             mov    0x8(%rax),%rdi
    11b5:       e8 26 ff ff ff          call   10e0 <strtol@plt>
    11ba:       89 05 40 5e d4 41       mov    %eax,0x41d45e40(%rip)        # 41d47000 <id>
    11c0:       48 89 c1                mov    %rax,%rcx
    11c3:       89 c6                   mov    %eax,%esi
    11c5:       85 c0                   test   %eax,%eax
    11c7:       0f 88 39 01 00 00       js     1306 <main+0x1b6>
    11cd:       49 b8 e5 8f a2 12 31    movabs $0x89705f3112a28fe5,%r8
    11d4:       5f 70 89 
    11d7:       bf 0a 00 00 00          mov    $0xa,%edi
    11dc:       0f 1f 40 00             nopl   0x0(%rax)
    11e0:       48 63 f6                movslq %esi,%rsi
    11e3:       48 63 c9                movslq %ecx,%rcx
    11e6:       48 69 f6 17 27 00 00    imul   $0x2717,%rsi,%rsi
    11ed:       48 69 c9 17 27 00 00    imul   $0x2717,%rcx,%rcx
    11f4:       48 83 c6 07             add    $0x7,%rsi
    11f8:       48 89 f0                mov    %rsi,%rax
    11fb:       48 83 c1 09             add    $0x9,%rcx
    11ff:       49 f7 e0                mul    %r8
    1202:       48 83 f1 01             xor    $0x1,%rcx
    1206:       48 89 c8                mov    %rcx,%rax
    1209:       48 c1 ea 1d             shr    $0x1d,%rdx
    120d:       48 69 d2 07 ca 9a 3b    imul   $0x3b9aca07,%rdx,%rdx
    1214:       29 d6                   sub    %edx,%esi
    1216:       49 f7 e0                mul    %r8
    1219:       48 c1 ea 1d             shr    $0x1d,%rdx
    121d:       48 69 d2 07 ca 9a 3b    imul   $0x3b9aca07,%rdx,%rdx
    1224:       29 d1                   sub    %edx,%ecx
    1226:       83 ef 01                sub    $0x1,%edi
    1229:       75 b5                   jne    11e0 <main+0x90>
    122b:       83 e6 07                and    $0x7,%esi
    122e:       83 e1 01                and    $0x1,%ecx
    1231:       89 35 dd 2d 00 00       mov    %esi,0x2ddd(%rip)        # 4014 <slowRank>
    1237:       89 0d d3 2d 00 00       mov    %ecx,0x2dd3(%rip)        # 4010 <workloadType>
    123d:       e8 4e 02 00 00          call   1490 <init()>
    1242:       bf 00 00 00 44          mov    $0x44000000,%edi
    1247:       e8 14 fe ff ff          call   1060 <MPI_Barrier@plt>
    124c:       e8 bf 02 00 00          call   1510 <lipsum()>
    1251:       bf 00 00 00 44          mov    $0x44000000,%edi
    1256:       e8 05 fe ff ff          call   1060 <MPI_Barrier@plt>
    125b:       e8 10 fe ff ff          call   1070 <MPI_Finalize@plt>
    1260:       8b 05 a2 5d d4 41       mov    0x41d45da2(%rip),%eax        # 41d47008 <mpiRank>
    1266:       85 c0                   test   %eax,%eax
    1268:       74 0a                   je     1274 <main+0x124>
    126a:       48 83 c4 18             add    $0x18,%rsp
    126e:       31 c0                   xor    %eax,%eax
    1270:       5d                      pop    %rbp
    1271:       41 5c                   pop    %r12
    1273:       c3                      ret
    1274:       48 8d 35 c7 0d 00 00    lea    0xdc7(%rip),%rsi        # 2042 <_IO_stdin_used+0x42>
    127b:       48 8d 3d be 2d 00 00    lea    0x2dbe(%rip),%rdi        # 4040 <std::cout@GLIBCXX_3.4>
    1282:       e8 09 fe ff ff          call   1090 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>
    1287:       8b 35 73 5d d4 41       mov    0x41d45d73(%rip),%esi        # 41d47000 <id>
    128d:       48 89 c7                mov    %rax,%rdi
    1290:       e8 9b fe ff ff          call   1130 <std::ostream::operator<<(int)@plt>
    1295:       48 89 c5                mov    %rax,%rbp
    1298:       48 8b 00                mov    (%rax),%rax
    129b:       48 8b 40 e8             mov    -0x18(%rax),%rax
    129f:       4c 8b a4 05 f0 00 00    mov    0xf0(%rbp,%rax,1),%r12
    12a6:       00 
    12a7:       4d 85 e4                test   %r12,%r12
    12aa:       74 6d                   je     1319 <main+0x1c9>
    12ac:       41 80 7c 24 38 00       cmpb   $0x0,0x38(%r12)
    12b2:       74 1b                   je     12cf <main+0x17f>
    12b4:       41 0f b6 44 24 43       movzbl 0x43(%r12),%eax
    12ba:       48 89 ef                mov    %rbp,%rdi
    12bd:       0f be f0                movsbl %al,%esi
    12c0:       e8 6b fd ff ff          call   1030 <std::ostream::put(char)@plt>
    12c5:       48 89 c7                mov    %rax,%rdi
    12c8:       e8 83 fd ff ff          call   1050 <std::ostream::flush()@plt>
    12cd:       eb 9b                   jmp    126a <main+0x11a>
    12cf:       4c 89 e7                mov    %r12,%rdi
    12d2:       e8 c9 fd ff ff          call   10a0 <std::ctype<char>::_M_widen_init() const@plt>
    12d7:       49 8b 04 24             mov    (%r12),%rax
    12db:       48 8d 0d ce 04 00 00    lea    0x4ce(%rip),%rcx        # 17b0 <std::ctype<char>::do_widen(char) const>
    12e2:       48 8b 50 30             mov    0x30(%rax),%rdx
    12e6:       b8 0a 00 00 00          mov    $0xa,%eax
    12eb:       48 39 ca                cmp    %rcx,%rdx
    12ee:       74 ca                   je     12ba <main+0x16a>
    12f0:       be 0a 00 00 00          mov    $0xa,%esi
    12f5:       4c 89 e7                mov    %r12,%rdi
    12f8:       ff d2                   call   *%rdx
    12fa:       eb be                   jmp    12ba <main+0x16a>
    12fc:       c7 05 fa 5c d4 41 ff    movl   $0xffffffff,0x41d45cfa(%rip)        # 41d47000 <id>
    1303:       ff ff ff 
    1306:       83 3d fb 5c d4 41 00    cmpl   $0x0,0x41d45cfb(%rip)        # 41d47008 <mpiRank>
    130d:       74 34                   je     1343 <main+0x1f3>
    130f:       bf 01 00 00 00          mov    $0x1,%edi
    1314:       e8 a7 fd ff ff          call   10c0 <exit@plt>
    1319:       e8 b2 fd ff ff          call   10d0 <std::__throw_bad_cast()@plt>
    131e:       83 3d e3 5c d4 41 00    cmpl   $0x0,0x41d45ce3(%rip)        # 41d47008 <mpiRank>
    1325:       75 e8                   jne    130f <main+0x1bf>
    1327:       48 8b 3d 32 2e 00 00    mov    0x2e32(%rip),%rdi        # 4160 <stderr@GLIBC_2.2.5>
    132e:       ba 08 00 00 00          mov    $0x8,%edx
    1333:       48 8d 35 ce 0c 00 00    lea    0xcce(%rip),%rsi        # 2008 <_IO_stdin_used+0x8>
    133a:       31 c0                   xor    %eax,%eax
    133c:       e8 cf fd ff ff          call   1110 <fprintf@plt>
    1341:       eb cc                   jmp    130f <main+0x1bf>
    1343:       48 8b 04 24             mov    (%rsp),%rax
    1347:       48 8b 3d 12 2e 00 00    mov    0x2e12(%rip),%rdi        # 4160 <stderr@GLIBC_2.2.5>
    134e:       48 8d 35 d5 0c 00 00    lea    0xcd5(%rip),%rsi        # 202a <_IO_stdin_used+0x2a>
    1355:       48 8b 10                mov    (%rax),%rdx
    1358:       31 c0                   xor    %eax,%eax
    135a:       e8 b1 fd ff ff          call   1110 <fprintf@plt>
    135f:       eb ae                   jmp    130f <main+0x1bf>
    1361:       66 66 2e 0f 1f 84 00    data16 cs nopw 0x0(%rax,%rax,1)
    1368:       00 00 00 00 
    136c:       0f 1f 40 00             nopl   0x0(%rax)


0000000000001510 <lipsum()>:
    1510:       41 57                   push   %r15
    1512:       41 56                   push   %r14
    1514:       41 55                   push   %r13
    1516:       41 54                   push   %r12
    1518:       55                      push   %rbp
    1519:       53                      push   %rbx
    151a:       48 83 ec 18             sub    $0x18,%rsp
    151e:       8b 0d ec 2a 00 00       mov    0x2aec(%rip),%ecx        # 4010 <workloadType>
    1524:       8b 15 de 5a d4 41       mov    0x41d45ade(%rip),%edx        # 41d47008 <mpiRank>
    152a:       8b 05 e4 2a 00 00       mov    0x2ae4(%rip),%eax        # 4014 <slowRank>
    1530:       85 c9                   test   %ecx,%ecx
    1532:       0f 85 49 01 00 00       jne    1681 <lipsum()+0x171>
    1538:       48 63 0d c1 5a d4 41    movslq 0x41d45ac1(%rip),%rcx        # 41d47000 <id>
    153f:       39 c2                   cmp    %eax,%edx
    1541:       be 70 17 00 00          mov    $0x1770,%esi
    1546:       b8 b8 0b 00 00          mov    $0xbb8,%eax
    154b:       48 0f 45 f0             cmovne %rax,%rsi
    154f:       48 8d 3d ea 74 f8 0b    lea    0xbf874ea(%rip),%rdi        # bf88a40 <ci>
    1556:       48 ba 0b d7 a3 70 3d    movabs $0xa3d70a3d70a3d70b,%rdx
    155d:       0a d7 a3 
    1560:       bb 64 00 00 00          mov    $0x64,%ebx
    1565:       48 69 c9 17 27 00 00    imul   $0x2717,%rcx,%rcx
    156c:       4c 8d 2d 0d 6f f0 17    lea    0x17f06f0d(%rip),%r13        # 17f08480 <ai>
    1573:       4c 8d 3d e6 71 f4 11    lea    0x11f471e6(%rip),%r15        # 11f48760 <bi>
    157a:       48 89 c8                mov    %rcx,%rax
    157d:       48 f7 ea                imul   %rdx
    1580:       48 8d 04 0a             lea    (%rdx,%rcx,1),%rax
    1584:       48 89 ca                mov    %rcx,%rdx
    1587:       48 c1 fa 3f             sar    $0x3f,%rdx
    158b:       48 c1 f8 06             sar    $0x6,%rax
    158f:       48 29 d0                sub    %rdx,%rax
    1592:       48 8d 04 80             lea    (%rax,%rax,4),%rax
    1596:       48 8d 14 80             lea    (%rax,%rax,4),%rdx
    159a:       48 89 c8                mov    %rcx,%rax
    159d:       48 c1 e2 02             shl    $0x2,%rdx
    15a1:       48 29 d0                sub    %rdx,%rax
    15a4:       48 ba c3 f5 28 5c 8f    movabs $0x28f5c28f5c28f5c3,%rdx
    15ab:       c2 f5 28 
    15ae:       48 05 aa 00 00 00       add    $0xaa,%rax
    15b4:       48 0f af c6             imul   %rsi,%rax
    15b8:       48 c1 e8 03             shr    $0x3,%rax
    15bc:       48 f7 e2                mul    %rdx
    15bf:       48 89 d0                mov    %rdx,%rax
    15c2:       48 c1 e8 02             shr    $0x2,%rax
    15c6:       41 89 c6                mov    %eax,%r14d
    15c9:       48 8d 2c 85 00 00 00    lea    0x0(,%rax,4),%rbp
    15d0:       00 
    15d1:       41 89 c4                mov    %eax,%r12d
    15d4:       4d 69 f6 1f 85 eb 51    imul   $0x51eb851f,%r14,%r14
    15db:       85 c0                   test   %eax,%eax
    15dd:       b8 04 00 00 00          mov    $0x4,%eax
    15e2:       48 0f 4f c5             cmovg  %rbp,%rax
    15e6:       31 ed                   xor    %ebp,%ebp
    15e8:       48 89 44 24 08          mov    %rax,0x8(%rsp)
    15ed:       49 c1 ee 25             shr    $0x25,%r14
    15f1:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    15f8:       48 8b 54 24 08          mov    0x8(%rsp),%rdx
    15fd:       31 f6                   xor    %esi,%esi
    15ff:       e8 3c fa ff ff          call   1040 <memset@plt>
    1604:       45 31 c9                xor    %r9d,%r9d
    1607:       48 89 c7                mov    %rax,%rdi
    160a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    1610:       31 f6                   xor    %esi,%esi
    1612:       31 c9                   xor    %ecx,%ecx
    1614:       0f 1f 40 00             nopl   0x0(%rax)
    1618:       69 c3 17 27 00 00       imul   $0x2717,%ebx,%eax
    161e:       05 d5 00 00 00          add    $0xd5,%eax
    1623:       99                      cltd
    1624:       41 f7 fc                idiv   %r12d
    1627:       48 63 c2                movslq %edx,%rax
    162a:       48 63 d1                movslq %ecx,%rdx
    162d:       48 89 c3                mov    %rax,%rbx
    1630:       48 69 c0 92 13 00 00    imul   $0x1392,%rax,%rax
    1637:       48 01 d0                add    %rdx,%rax
    163a:       41 8b 54 8d 00          mov    0x0(%r13,%rcx,4),%edx
    163f:       48 83 c1 01             add    $0x1,%rcx
    1643:       41 0f af 14 87          imul   (%r15,%rax,4),%edx
    1648:       01 d6                   add    %edx,%esi
    164a:       4c 39 f1                cmp    %r14,%rcx
    164d:       75 c9                   jne    1618 <lipsum()+0x108>
    164f:       42 89 34 8f             mov    %esi,(%rdi,%r9,4)
    1653:       49 83 c1 01             add    $0x1,%r9
    1657:       45 39 cc                cmp    %r9d,%r12d
    165a:       7f b4                   jg     1610 <lipsum()+0x100>
    165c:       83 c5 01                add    $0x1,%ebp
    165f:       48 81 c7 48 4e 00 00    add    $0x4e48,%rdi
    1666:       49 81 c5 48 4e 00 00    add    $0x4e48,%r13
    166d:       44 39 e5                cmp    %r12d,%ebp
    1670:       7c 86                   jl     15f8 <lipsum()+0xe8>
    1672:       48 83 c4 18             add    $0x18,%rsp
    1676:       5b                      pop    %rbx
    1677:       5d                      pop    %rbp
    1678:       41 5c                   pop    %r12
    167a:       41 5d                   pop    %r13
    167c:       41 5e                   pop    %r14
    167e:       41 5f                   pop    %r15
    1680:       c3                      ret
    1681:       48 63 0d 78 59 d4 41    movslq 0x41d45978(%rip),%rcx        # 41d47000 <id>
    1688:       39 c2                   cmp    %eax,%edx
    168a:       be d0 07 00 00          mov    $0x7d0,%esi
    168f:       b8 e8 03 00 00          mov    $0x3e8,%eax
    1694:       48 0f 45 f0             cmovne %rax,%rsi
    1698:       48 8d 3d 01 6b ec 1d    lea    0x1dec6b01(%rip),%rdi        # 1dec81a0 <cd>
    169f:       48 ba 0b d7 a3 70 3d    movabs $0xa3d70a3d70a3d70b,%rdx
    16a6:       0a d7 a3 
    16a9:       48 69 c9 17 27 00 00    imul   $0x2717,%rcx,%rcx
    16b0:       48 8d 2d 29 5f dc 35    lea    0x35dc5f29(%rip),%rbp        # 35dc75e0 <ad>
    16b7:       48 89 c8                mov    %rcx,%rax
    16ba:       48 f7 ea                imul   %rdx
    16bd:       48 8d 04 0a             lea    (%rdx,%rcx,1),%rax
    16c1:       48 89 ca                mov    %rcx,%rdx
    16c4:       48 c1 fa 3f             sar    $0x3f,%rdx
    16c8:       48 c1 f8 06             sar    $0x6,%rax
    16cc:       48 29 d0                sub    %rdx,%rax
    16cf:       48 8d 04 80             lea    (%rax,%rax,4),%rax
    16d3:       48 8d 14 80             lea    (%rax,%rax,4),%rdx
    16d7:       48 89 c8                mov    %rcx,%rax
    16da:       48 c1 e2 02             shl    $0x2,%rdx
    16de:       48 29 d0                sub    %rdx,%rax
    16e1:       48 ba c3 f5 28 5c 8f    movabs $0x28f5c28f5c28f5c3,%rdx
    16e8:       c2 f5 28 
    16eb:       48 05 aa 00 00 00       add    $0xaa,%rax
    16f1:       48 0f af c6             imul   %rsi,%rax
    16f5:       48 c1 e8 03             shr    $0x3,%rax
    16f9:       48 f7 e2                mul    %rdx
    16fc:       48 89 d0                mov    %rdx,%rax
    16ff:       48 c1 e8 02             shr    $0x2,%rax
    1703:       85 c0                   test   %eax,%eax
    1705:       4c 8d 24 c5 00 00 00    lea    0x0(,%rax,8),%r12
    170c:       00 
    170d:       89 c3                   mov    %eax,%ebx
    170f:       b8 08 00 00 00          mov    $0x8,%eax
    1714:       4c 0f 4e e0             cmovle %rax,%r12
    1718:       45 31 ed                xor    %r13d,%r13d
    171b:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
    1720:       4c 89 e2                mov    %r12,%rdx
    1723:       31 f6                   xor    %esi,%esi
    1725:       e8 16 f9 ff ff          call   1040 <memset@plt>
    172a:       48 8d 15 8f 64 e4 29    lea    0x29e4648f(%rip),%rdx        # 29e47bc0 <bd>
    1731:       31 c9                   xor    %ecx,%ecx
    1733:       66 0f ef d2             pxor   %xmm2,%xmm2
    1737:       48 89 c7                mov    %rax,%rdi
    173a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    1740:       31 c0                   xor    %eax,%eax
    1742:       66 0f 28 ca             movapd %xmm2,%xmm1
    1746:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
    174d:       00 00 00 
    1750:       f2 0f 10 44 c5 00       movsd  0x0(%rbp,%rax,8),%xmm0
    1756:       f2 0f 59 04 c2          mulsd  (%rdx,%rax,8),%xmm0
    175b:       48 83 c0 01             add    $0x1,%rax
    175f:       f2 0f 58 c8             addsd  %xmm0,%xmm1
    1763:       39 c3                   cmp    %eax,%ebx
    1765:       7f e9                   jg     1750 <lipsum()+0x240>
    1767:       f2 0f 11 0c cf          movsd  %xmm1,(%rdi,%rcx,8)
    176c:       48 83 c1 01             add    $0x1,%rcx
    1770:       48 81 c2 90 9c 00 00    add    $0x9c90,%rdx
    1777:       39 cb                   cmp    %ecx,%ebx
    1779:       7f c5                   jg     1740 <lipsum()+0x230>
    177b:       41 83 c5 01             add    $0x1,%r13d
    177f:       48 81 c7 90 9c 00 00    add    $0x9c90,%rdi
    1786:       48 81 c5 90 9c 00 00    add    $0x9c90,%rbp
    178d:       41 39 dd                cmp    %ebx,%r13d
    1790:       7c 8e                   jl     1720 <lipsum()+0x210>
    1792:       48 83 c4 18             add    $0x18,%rsp
    1796:       5b                      pop    %rbx
    1797:       5d                      pop    %rbp
    1798:       41 5c                   pop    %r12
    179a:       41 5d                   pop    %r13
    179c:       41 5e                   pop    %r14
    179e:       41 5f                   pop    %r15
    17a0:       c3                      ret
    17a1:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
    17a8:       00 00 00 
    17ab:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

使用Ghidra进行反编译

得到lipsum()函数和main函数的等效源代码,得出的源码可读性还比较差,我们还需要进一步处理。

1
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
undefined8 main(int param_1, undefined8 *param_2)
{
    long *plVar1;
    ulong uVar2;
    basic_ostream *this;
    long *plVar3;
    uint uVar4;
    uint uVar5;
    ulong uVar6;
    int iVar7;
    undefined8 *local_28;
    int local_1c[3];

    local_28 = param_2;
    local_1c[0] = param_1;
    MPI_Init(local_1c, &local_28);
    MPI_Comm_size(0x44000000, &mpiSize);
    MPI_Comm_rank(0x44000000);
    if (mpiSize == 8) {
        if (local_1c[0] == 2) {
            uVar2 = strtol((char *)local_28[1], (char **)0x0, 10);
            id = (int)uVar2;
            uVar6 = uVar2 & 0xffffffff;
            if (-1 < id) {
                iVar7 = 10;
                do {
                    uVar6 = (long)(int)uVar6 * 0x2717 + 7;
                    uVar2 = (long)(int)uVar2 * 0x2717 + 9U ^ 1;
                    uVar5 = (int)uVar6 + (int)(uVar6 / 0x3b9aca07) * -0x3b9aca07;
                    uVar6 = (ulong)uVar5;
                    uVar4 = (int)uVar2 + (int)(uVar2 / 0x3b9aca07) * -0x3b9aca07;
                    uVar2 = (ulong)uVar4;
                    iVar7 = iVar7 + -1;
                } while (iVar7 != 0);
                slowRank = uVar5 & 7;
                workloadType = uVar4 & 1;
                init();
                MPI_Barrier(0x44000000);
                lipsum();
                MPI_Barrier(0x44000000);
                MPI_Finalize();
                if (mpiRank != 0) {
                    return 0;
                }
                this = std::operator<<((basic_ostream *)std::cout, "Sucesss ");
                plVar3 = (long *)std::basic_ostream<char, std::char_traits<char>>::operator<<
                                 ((basic_ostream<char, std::char_traits<char>> *)this, id);
                plVar1 = *(long **)((long)plVar3 + *(long *)(*plVar3 + -0x18) + 0xf0);
                if (plVar1 != (long *)0x0) {
                    if (*(char *)(plVar1 + 7) == '\0') {
                        std::ctype<char>::_M_widen_init();
                        if (*(code **)(*plVar1 + 0x30) != std::ctype<char>::do_widen) {
                            (**(code **)(*plVar1 + 0x30))(plVar1, 10);
                        }
                    }
                    std::basic_ostream<char, std::char_traits<char>>::put((char)plVar3);
                    std::basic_ostream<char, std::char_traits<char>>::flush();
                    return 0;
                }
                std::__throw_bad_cast();
                goto LAB_0010131e;
            }
        }
        else {
            id = -1;
        }
        if (mpiRank == 0) {
            fprintf(stderr, "Usage: %s <Student ID>\n", *local_28);
        }
    }
    else {
    LAB_0010131e:
        if (mpiRank == 0) {
            fprintf(stderr, "Please run with %d MPI prcoesses\n", 8);
        }
    }
    /* WARNING: Subroutine does not return */
    exit(1);
}

/* WARNING: Unknown calling convention -- yet parameter storage is locked */
/* lipsum() */
void lipsum(void)
{
    long lVar1;
    long lVar2;
    int iVar3;
    ulong uVar4;
    void *pvVar5;
    int iVar6;
    ulong uVar7;
    long lVar8;
    int iVar9;
    int iVar10;
    long lVar11;
    undefined1 *puVar12;
    size_t sVar13;
    undefined1 *puVar14;
    double dVar15;

    if (workloadType == 0) {
        lVar11 = 6000;
        if (mpiRank != slowRank) {
            lVar11 = 3000;
        }
        puVar12 = ci;
        lVar8 = 100;
        puVar14 = ai;
        uVar4 = (ulong)((((long)id * 0x2717) % 100 + 0xaa) * lVar11) / 200;
        iVar3 = (int)uVar4;
        sVar13 = 4;
        if (0 < iVar3) {
            sVar13 = uVar4 * 4;
        }
        iVar9 = 0;
        do {
            pvVar5 = memset(puVar12, 0, sVar13);
            lVar11 = 0;
            do {
                iVar10 = 0;
                uVar7 = 0;
                do {
                    lVar8 = (long)(((int)lVar8 * 0x2717 + 0xd5) % iVar3);
                    iVar6 = (int)uVar7;
                    lVar1 = uVar7 * 4;
                    uVar7 = uVar7 + 1;
                    iVar10 = iVar10 + *(int *)(puVar14 + lVar1) *
                                      *(int *)(bi + (lVar8 * 0x1392 + (long)iVar6) * 4);
                } while (uVar7 != (uVar4 & 0xffffffff) / 100);
                *(int *)((long)pvVar5 + lVar11 * 4) = iVar10;
                lVar11 = lVar11 + 1;
            } while ((int)lVar11 < iVar3);
            iVar9 = iVar9 + 1;
            puVar12 = (undefined1 *)((long)pvVar5 + 0x4e48);
            puVar14 = puVar14 + 0x4e48;
        } while (iVar9 < iVar3);
        return;
    }
    lVar11 = 2000;
    if (mpiRank != slowRank) {
        lVar11 = 1000;
    }
    puVar14 = cd;
    puVar12 = ad;
    uVar4 = (ulong)((((long)id * 0x2717) % 100 + 0xaa) * lVar11) / 200;
    iVar3 = (int)uVar4;
    sVar13 = uVar4 * 8;
    if (iVar3 < 1) {
        sVar13 = 8;
    }
    iVar9 = 0;
    do {
        pvVar5 = memset(puVar14, 0, sVar13);
        puVar14 = bd;
        lVar11 = 0;
        do {
            lVar8 = 0;
            dVar15 = 0.0;
            do {
                lVar2 = lVar8 * 8;
                lVar1 = lVar8 * 8;
                lVar8 = lVar8 + 1;
                dVar15 = dVar15 + *(double *)(puVar12 + lVar2) * *(double *)(puVar14 + lVar1);
            } while ((int)lVar8 < iVar3);
            *(double *)((long)pvVar5 + lVar11 * 8) = dVar15;
            lVar11 = lVar11 + 1;
            puVar14 = puVar14 + 0x9c90;
        } while ((int)lVar11 < iVar3);
        iVar9 = iVar9 + 1;
        puVar14 = (undefined1 *)((long)pvVar5 + 0x9c90);
        puVar12 = puVar12 + 0x9c90;
    } while (iVar9 < iVar3);
    return;
}

使用Grok3大模型进行整理

把这段可读性极差的代码交给Grok3大模型进行整理,得到最后近似版的源代码,真相终于浮出水面。

1
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <mpi.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

// 全局变量(根据反编译代码推测)
int id = -1;          // 学生 ID 或输入参数
int mpiRank;          // 当前进程的 MPI 排名
int mpiSize;          // MPI 进程总数
int slowRank;         // 慢速进程的排名
int workloadType;     // 工作负载类型(0 或 1)
int* ai;              // 输入数组(整数)
int* bi;              // 输入数组(整数)
int* ci;              // 输出数组(整数)
double* ad;           // 输入数组(浮点数)
double* bd;           // 输入数组(浮点数)
double* cd;           // 输出数组(浮点数)


// 工作负载函数
void lipsum() {
    if (workloadType == 0) {
        // 整数运算工作负载
        int iterations = (mpiRank == slowRank) ? 6000 : 3000; // 慢速进程迭代更多
        int size = (((id * 0x2717) % 100 + 0xAA) * iterations) / 200; // 计算数组大小
        size_t bufferSize = (size > 0) ? size * sizeof(int) : 4 * sizeof(int);

        int* output = ci; // 输出缓冲区
        int* inputA = ai; // 输入缓冲区 A
        for (int i = 0; i < size; ++i) {
            memset(output, 0, bufferSize); // 清零输出缓冲区
            long seed = 100; // 初始种子
            for (int j = 0; j < size; ++j) {
                int sum = 0;
                for (int k = 0; k < size / 100; ++k) {
                    seed = ((seed * 0x2717 + 0xD5) % size); // 更新种子
                    sum += inputA[k * sizeof(int)] * bi[(seed * 0x1392 + k) * sizeof(int) / sizeof(int)];
                }
                output[j] = sum;
            }
            output += 0x4E48 / sizeof(int); // 移动到下一块缓冲区
            inputA += 0x4E48 / sizeof(int);
        }
    } else {
        // 浮点运算工作负载
        int iterations = (mpiRank == slowRank) ? 2000 : 1000; // 慢速进程迭代更多
        int size = (((id * 0x2717) % 100 + 0xAA) * iterations) / 200; // 计算数组大小
        size_t bufferSize = (size > 0) ? size * sizeof(double) : 8 * sizeof(double);

        double* output = cd; // 输出缓冲区
        double* inputA = ad; // 输入缓冲区 A
        double* inputB = bd; // 输入缓冲区 B
        for (int i = 0; i < size; ++i) {
            memset(output, 0, bufferSize); // 清零输出缓冲区
            for (int j = 0; j < size; ++j) {
                double sum = 0.0;
                for (int k = 0; k < size; ++k) {
                    sum += inputA[k] * inputB[k];
                }
                output[j] = sum;
                inputB += 0x9C90 / sizeof(double); // 移动到下一块缓冲区
            }
            output += 0x9C90 / sizeof(double); // 移动到下一块缓冲区
            inputA += 0x9C90 / sizeof(double);
        }
    }
}

int main(int argc, char* argv[]) {
    // 初始化 MPI
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &mpiSize); // 获取进程总数
    MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); // 获取当前进程排名

    // 检查是否使用 8 个 MPI 进程
    if (mpiSize != 8) {
        if (mpiRank == 0) {
            fprintf(stderr, "Please run with %d MPI processes\n", 8);
        }
        MPI_Finalize();
        exit(1);
    }

    // 检查命令行参数
    if (argc == 2) {
        id = std::atoi(argv[1]); // 解析学生 ID
        if (id >= 0) {
            // 计算 slowRank 和 workloadType
            unsigned int seed1 = id;
            unsigned int seed2 = id;
            for (int i = 0; i < 10; ++i) {
                seed1 = seed1 * 0x2717 + 7; // 更新种子 1
                seed2 = (seed2 * 0x2717 + 9) ^ 1; // 更新种子 2
                seed1 = seed1 % 0x3B9ACA07; // 模运算
                seed2 = seed2 % 0x3B9ACA07;
            }
            slowRank = seed1 & 7; // 确定慢速进程
            workloadType = seed2 & 1; // 确定工作负载类型(0 或 1)

            // 执行工作负载
            init();
            MPI_Barrier(MPI_COMM_WORLD); // 同步
            lipsum();
            MPI_Barrier(MPI_COMM_WORLD); // 同步
            MPI_Finalize();

            // 主进程输出结果
            if (mpiRank == 0) {
                std::cout << "Success " << id << std::endl;
            }
            return 0;
        }
    }

    // 参数错误处理
    if (mpiRank == 0) {
        fprintf(stderr, "Usage: %s <Student ID>\n", argv[0]);
    }
    MPI_Finalize();
    exit(1);
}

可以发现依赖于输入参数的全局变量有两个分别是slowRankworkloadTypelipsum()函数会根据这两个参数来执行不同的逻辑,前者决定八个进程中哪个进程设置为慢速进程,后者决定工作负载种类是整数运算还是浮点运算,具体截取如下。

1
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
#include <mpi.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

//...
int slowRank;         // 慢速进程的排名
int workloadType;     // 工作负载类型(0 或 1)


// 工作负载函数
void lipsum() {
    if (workloadType == 0) {
        // 整数运算工作负载
        int iterations = (mpiRank == slowRank) ? 6000 : 3000; // 慢速进程迭代更多
		//...
        }
    } else {
        // 浮点运算工作负载
        int iterations = (mpiRank == slowRank) ? 2000 : 1000; // 慢速进程迭代更多
        //...
    }
}

int main(int argc, char* argv[]) {
	//...
    // 检查命令行参数
    //...
    id = std::atoi(argv[1]); // 解析学生 ID
    if (id >= 0) {
        // 计算 slowRank 和 workloadType
        unsigned int seed1 = id;
        unsigned int seed2 = id;
        for (int i = 0; i < 10; ++i) {
            seed1 = seed1 * 0x2717 + 7; // 更新种子 1
            seed2 = (seed2 * 0x2717 + 9) ^ 1; // 更新种子 2
            seed1 = seed1 % 0x3B9ACA07; // 模运算
            seed2 = seed2 % 0x3B9ACA07;
        }
        slowRank = seed1 & 7; // 确定慢速进程
        workloadType = seed2 & 1; // 确定工作负载类型(0 或 1)

     //...
    }
    //...
    // 参数错误处理
	//...
}

将十六进制转化为十进制,我们可以看到真正的逻辑如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
    // 参数为同学学号
	val1 = studentId;
    val2 = studentId;
    
    // Perform the calculations
    for(int i = 0; i < 10; i++) {
        val1 = (val1 * 10007 + 7) % 1000000007;
        val2 = (val2 * 10007 + 9) % 1000000007;
    }
    
    // Calculate task allocation parameters
    slowRank = val1 % 8;
    workloadType = val2 % 2;

总结

一次有趣的逆向工程之旅就这样结束了,我们可以给逆向工程(Reverse Engineering)下一个定义:在不依赖原始设计文档或源代码的情况下,分析一个已有系统、程序、设备或对象的结构、功能和行为,推导出其设计原理、实现细节、内部工作机制或源代码的过程。

附上一些大佬对逆向工程的评价作为结束语。

  1. Linus Torvalds(Linux 内核创始人)

    “如果你能通过逆向工程理解一个系统,你就有了重现或改进它的自由。这正是开源精神的延伸。”

  2. Bruce Schneier(密码学与安全专家)

    “逆向工程是安全研究的基石。没有它,我们无法真正理解系统的弱点,也无法构建更强的防御。”

  3. Ken Thompson(UNIX 创始人之一)

    “要真正理解一个程序必须能够追溯其每一行代码。逆向工程让我们看到隐藏在二进制背后的真相。”

  4. John Carmack(游戏开发者,id Software 创始人)

    “逆向工程不是偷窃,它是学习。当你拆解一个系统,你会发现它的美与瑕疵。”

  5. Ellen Ullman(程序员,作家)

    “逆向工程就像考古,挖掘代码的每一层,试图还原设计者的意图。”

本文由作者按照 CC BY 4.0 进行授权

Hello World!

Ocaml(1) | Vincent's Technical Reports (Vol. 2)