00401205 JNZ SHORT cryptex.0040123C
00401207 PUSH EDI
00401208 MOV ECX,4
0040120D MOV EDI,cryptex.00405038
00401212 MOV ESI,cryptex.00406070
00401217 XOR EDX,EDX
00401219 REPE CMPS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
0040121B POP EDI
0040121C JE SHORT cryptex.00401234
0040121E PUSH cryptex.00403170 ; format = “ERROR: Invalid
password. Unable to process
file.”
00401223 CALL DS:[<&MSVCR71.printf>] ; printf
00401229 ADD ESP,4
0040122C PUSH 1 ; status = 1
0040122E CALL DS:[<&MSVCR71.exit>] ; exit
00401234 MOV EAX,1
00401239 POP ESI
0040123A POP ECX
0040123B RETN
0040123C PUSH cryptex.0040313C ; format = “ERROR: Invalid
Cryptex9 signature in file
header!”
00401241 CALL DS:[<&MSVCR71.printf>] ; printf
00401247 ADD ESP,4
0040124A PUSH 1 ; status = 1
0040124C CALL DS:[<&MSVCR71.exit>] ; exit
Listing 6.3 (continued)
It looks as if the function in Listing 6.3 performs some kind of header verifi-
cation on the archive. It starts out by moving the file pointer to zero (using the
SetFilePointerAPI), and proceeds to read the first 0x28bytes from the
archive file using the ReadFileAPI. The header data is read into a data struc-
ture that is stored at 00406058. It is quite easy to see that this address is essen-
tially a global variable of some sort (as opposed to a heap or stack address),
because it is very close to the code address itself. A quick look at the Executable
Modules window shows us that the program’s executable, Cryptex.exewas
loaded into 00400000. This indicates that 00406058 is somewhere within
the Cryptex.exemodule, probably in the data section (you could verify this
by checking the module’s data section RVA using an executable dumping tool,
but it is quite obvious).
The function proceeds to compare the first two DWORDs in the header with
the hard-coded values 70597243 and 39586554. If the first two DWORDs
don’t match these constants, the function jumps to 0040123Cand displays the
message ERROR: Invalid Cryptex9 signature in file header!. A
Deciphering File Formats 209