*Description: checksum_md5 demonstrates a checksum can be used for generating a MD5 constant initialization value. =========================================================== *Usage: checksum_md5.exe *Output: The MD5 value of Abraham Lincoln's Gettysburg Address. =========================================================== *Note: This program uses the same source to compute an MD5 hash as the other samples. Much of the MD5 computation takes place in the execution of the unsigned char array code_buf. code_buf is an array of hex values which, when unpacked correctly, form the executable code of the original MD5 program. Since it may seem suspicious to use source code with binary code already in it, it should be noted that code_buf can be replaced with any array of binary code. To use another program instead of the MD5 program, use an “inlined” version of it. Meaning any function calls in the source code should be directly replaced by the function’s code; in addition, any global variables should be moved into the function body. These measures are all taken to ensure there are no absolute references, so that the code produced is effectively portable. After that, convert the code to a hex string. This can be done by compiling the function’s code, then manually going through each instruction in a debugger and copying its opcode into the hex array. Similarly, the output of “objdump -d” may be used to obtain the instruction encodings. Or a simple routine can be written in the source which parses the function code from beginning to end, then produces its hex string in the appropriate format. In the samples, the MD5 code was produced from http://people.csail.mit.edu/rivest/Md5.c. The function MDString() in our source was assembled from “inlining” the original source code into one function. Then code_buf was produced as mentioned above, from parsing MDString() from beginning to end using C labels. =========================================================== *checksum_md5 algorithm: checksum-md5 uses the checksum as the MD5 initialization constant, then the MD5 value is printed to the screen using printf(). The intuition is that an incorrect checksum will yield an incorrect answer printed to stdout, while a correct checksum will yield a correct answer printed to stdout. First, a for loop adds every byte in code_buf to checksum. Then, checksum and the constant 0x6740E9CB are added to (in the correct case) produce 0x67452301. This sum is one of the “magic initialization constants” from line 150 of the original source code: “mdContext->buf[0] = (UINT4)0x67452301;”. After the edit has been made to code_buf to yield a correct MD5 seed, code_buf is casted to a function pointer then invoked.