1. Trang chủ
  2. » Kỹ Năng Mềm

reversing secrets of reverse engineering phần 5 doc

62 270 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

The first hit comes from an internal system call made by ADVAPI32.DLL. Releasing the debugger brings it back to ReadFile again, except that again, it was called internally from system code. You will very quickly realize that there are way too many calls to ReadFile for this approach to work; this API is used by the system heavily. There are many alternative approaches you could take at this point, depend- ing on the particular application. One option would be to try and restrict the ReadFile breakpoint to calls made on the archive file. You could do this by first placing a breakpoint on the API call that opens or creates the archive (this is probably going to be a call to the CreateFile API), obtain the archive han- dle from that call, and place a selective breakpoint on ReadFile that only breaks when the specific handle to the Cryptex archive is specified (such breakpoints are supported by most debuggers). This would really reduce the number of calls—you’d only see the relevant calls where Cryptex reads from the archive, and not hundreds of irrelevant system calls. On the other hand, since Cryptex is really a fairly simple program, you could just let it run until it reached the key-generation function from Listing 6.5. At this point you could just step through the rest of the code until you reach interesting code areas that decipher the directory data structures. Keep in mind that in most real programs you’d have to come up with a better idea for where to place your breakpoint, because simply stepping through the pro- gram is going to be an unreasonably tedious task. You can start by placing a breakpoint at the end of the key-generation func- tion, on address 00402416. Once you reach that address, you can step back into the calling function and step through several irrelevant code sequences, including a call into a function that apparently performs the actual opening of the archive and ends up calling into 004011C0, which is the function ana- lyzed in Listing 6.3. The next function call goes into 004019F0, and (based on a quick look at it) appears to be what we’re looking for. Listing 6.6 lists the OllyDbg-generated disassembly for this function. 004019F0 SUB ESP,8 004019F3 PUSH EBX 004019F4 PUSH EBP 004019F5 PUSH ESI 004019F6 MOV ESI,SS:[ESP+18] 004019FA XOR EBX,EBX 004019FC PUSH EBX ; Origin => FILE_BEGIN 004019FD PUSH EBX ; pOffsetHi => NULL 004019FE PUSH EBX ; OffsetLo => 0 004019FF PUSH ESI ; hFile 00401A00 CALL DS:[<&KERNEL32.SetFilePointer>] 00401A06 PUSH EBX ; pOverlapped => NULL Listing 6.6 Disassembly of function that lists all files within a Cryptex archive. (continued) Deciphering File Formats 219 11_574817 ch06.qxd 3/16/05 8:43 PM Page 219 00401A07 LEA EAX,SS:[ESP+14] ; 00401A0B PUSH EAX ; pBytesRead 00401A0C PUSH 28 ; BytesToRead = 28 (40.) 00401A0E PUSH cryptex.00406058 ; Buffer = cryptex.00406058 00401A13 PUSH ESI ; hFile 00401A14 CALL DS:[<&KERNEL32.ReadFile>] 00401A1A MOV ECX,SS:[ESP+1C] 00401A1E MOV EDX,DS:[406064] 00401A24 PUSH ECX 00401A25 PUSH EDX 00401A26 PUSH ESI 00401A27 CALL cryptex.00401030 00401A2C MOV EBP,DS:[<&MSVCR71.printf>] 00401A32 MOV ESI,DS:[406064] 00401A38 PUSH cryptex.00403234 ; format = “ File Size File Name” 00401A3D MOV DWORD PTR SS:[ESP+1C],cryptex.00405050 00401A45 CALL EBP ; printf 00401A47 ADD ESP,10 00401A4A TEST ESI,ESI 00401A4C JE SHORT cryptex.00401ACD 00401A4E PUSH EDI 00401A4F MOV EDI,SS:[ESP+24] 00401A53 JMP SHORT cryptex.00401A60 00401A55 LEA ESP,SS:[ESP] 00401A5C LEA ESP,SS:[ESP] 00401A60 MOV ESI,SS:[ESP+10] 00401A64 ADD ESI,8 00401A67 MOV DWORD PTR SS:[ESP+14],1A 00401A6F NOP 00401A70 MOV EAX,DS:[ESI] 00401A72 TEST EAX,EAX 00401A74 JE SHORT cryptex.00401A9A 00401A76 MOV EDX,EAX 00401A78 SHL EDX,0A 00401A7B SUB EDX,EAX 00401A7D ADD EDX,EDX 00401A7F LEA ECX,DS:[ESI+14] 00401A82 ADD EDX,EDX 00401A84 PUSH ECX 00401A85 SHR EDX,0A 00401A88 PUSH EDX 00401A89 PUSH cryptex.00403250 ; ASCII “ %10dK %s” 00401A8E CALL EBP 00401A90 MOV EAX,DS:[ESI] 00401A92 ADD DS:[EDI],EAX 00401A94 ADD ESP,0C 00401A97 ADD EBX,1 Listing 6.6 (continued) 220 Chapter 6 11_574817 ch06.qxd 3/16/05 8:43 PM Page 220 00401A9A ADD ESI,98 00401AA0 SUB DWORD PTR SS:[ESP+14],1 00401AA5 JNZ SHORT cryptex.00401A70 00401AA7 MOV ECX,SS:[ESP+10] 00401AAB MOV ESI,DS:[ECX] 00401AAD TEST ESI,ESI 00401AAF JE SHORT cryptex.00401ACC 00401AB1 MOV EDX,SS:[ESP+20] 00401AB5 MOV EAX,SS:[ESP+1C] 00401AB9 PUSH EDX 00401ABA PUSH ESI 00401ABB PUSH EAX 00401ABC CALL cryptex.00401030 00401AC1 ADD ESP,0C 00401AC4 TEST ESI,ESI 00401AC6 MOV SS:[ESP+10],EAX 00401ACA JNZ SHORT cryptex.00401A60 00401ACC POP EDI 00401ACD POP ESI 00401ACE POP EBP 00401ACF MOV EAX,EBX 00401AD1 POP EBX 00401AD2 ADD ESP,8 00401AD5 RETN Listing 6.6 (continued) This function starts out with a familiar sequence that reads the Cryptex header into memory. This is obvious because it is reading 0x28 bytes from off- set 0 in the file. It then proceeds to call into a function at 00401030, which, upon stepping into it, looks quite important. Listing 6.7 provides a disassem- bly of the function at 00401030. 00401030 PUSH ECX 00401031 PUSH ESI 00401032 MOV ESI,SS:[ESP+C] 00401036 PUSH EDI 00401037 MOV EDI,SS:[ESP+14] 0040103B MOV ECX,1008 00401040 LEA EAX,DS:[EDI-1] 00401043 MUL ECX 00401045 ADD EAX,28 00401048 ADC EDX,0 0040104B PUSH 0 ; Origin = FILE_BEGIN 0040104D MOV SS:[ESP+18],EDX ; Listing 6.7 A disassembly of Cryptex’s cluster decryption function. (continued) Deciphering File Formats 221 11_574817 ch06.qxd 3/16/05 8:43 PM Page 221 00401051 LEA EDX,SS:[ESP+18] ; 00401055 PUSH EDX ; pOffsetHi 00401056 PUSH EAX ; OffsetLo 00401057 PUSH ESI ; hFile 00401058 CALL DS:[<&KERNEL32.SetFilePointer>] 0040105E PUSH 0 ; pOverlapped = NULL 00401060 LEA EAX,SS:[ESP+C] ; 00401064 PUSH EAX ; pBytesRead 00401065 PUSH 1008 ; BytesToRead = 1008 (4104.) 0040106A PUSH cryptex.00405050 ; Buffer = cryptex.00405050 0040106F PUSH ESI ; hFile 00401070 CALL DS:[<&KERNEL32.ReadFile>] 00401076 TEST EAX,EAX 00401078 JE SHORT cryptex.004010CB 0040107A MOV EAX,SS:[ESP+18] 0040107E TEST EAX,EAX 00401080 MOV DWORD PTR SS:[ESP+14],1008 00401088 JE SHORT cryptex.004010C2 0040108A LEA ECX,SS:[ESP+14] 0040108E PUSH ECX 0040108F PUSH cryptex.00405050 00401094 PUSH 0 00401096 PUSH 1 00401098 PUSH 0 0040109A PUSH EAX 0040109B CALL DS:[<&ADVAPI32.CryptDecrypt>] 004010A1 TEST EAX,EAX 004010A3 JNZ SHORT cryptex.004010C2 004010A5 CALL DS:[<&KERNEL32.GetLastError>] 004010AB PUSH EDI ; <%d> 004010AC PUSH cryptex.004030E8 ; format = “ERROR: Unable to decrypt block from cluster %d.” 004010B1 CALL DS:[<&MSVCR71.printf>] 004010B7 ADD ESP,8 004010BA PUSH 1 ; status = 1 004010BC CALL DS:[<&MSVCR71.exit>] 004010C2 POP EDI 004010C3 MOV EAX,cryptex.00405050 004010C8 POP ESI 004010C9 POP ECX 004010CA RETN 004010CB POP EDI 004010CC XOR EAX,EAX 004010CE POP ESI 004010CF POP ECX 004010D0 RETN Listing 6.7 (continued) 222 Chapter 6 11_574817 ch06.qxd 3/16/05 8:43 PM Page 222 This function starts out by reading a fixed size (4,104-byte) chunk of data from the archive file. The interesting thing about this read operation is how the starting address is calculated. The function receives a parameter that is multi- plied by 4,104, adds 0x28, and is then used as the file offset from where to start reading. This exposes an important detail about the internal organization of Cryptex files: they appear to be divided into data blocks that are 4,104 bytes long. Adding 0x28 to the file offset is simply a way to skip the file header. The second parameter that this function takes appears to be some kind of a block number that the function must read. After the data is read into memory, the function proceeds to decrypt it using the CryptDecrypt function. As expected, the data-length parameter (which is the sixth parameter passed to this function) is again hard-coded to 4104. It is interesting to look at the error message that is printed if this function fails. It reveals that this function is attempting to read and decrypt a cluster, which is probably just a fancy name for what I classified as those fixed-sized data blocks. If CryptDecrypt is successful, the function simply returns to the caller while returning the address of the newly decrypted block. Analyzing a File Entry Since you’re working under the assumption that the block that was just read is the archive’s file directory or some other part of its header, your next step is to take the decrypted block and attempt to study it and establish how it’s struc- tured. The following memory dump shows the contents of the decrypted block I obtained while trying to list the files in the Test1.crx archive created earlier. 00405050 00 00 00 00 02 00 00 00 00405058 01 00 00 00 52 EB DD 0C Rë_. 00405060 D4 CB 55 D9 A4 CD E1 C6 ÔËUÙ¤ÍáÆ 00405068 96 6C 9C 3C 61 73 74 65 –lœ<aste 00405070 72 69 73 6B 73 2E 74 78 risks.tx 00405078 74 00 00 00 00 00 00 00 t As you can see, you’re in the right place; the memory block contains the file name asterisks.txt, which you encrypted into this archive earlier. The question now is: What is in those 28 bytes that precede the file name? One thing to do right away is to try and view the data in a different way. In the pre- ceding dump I used an ASCII view because I wanted to be able to see the file name string, but it might be easier to make out other fields by using a 32-bit view on this entry. The following are the first 28 bytes viewed as a sequence of 32-bit hexadecimal numbers: 00405050 00000000 00000002 00000001 0CDDEB52 00405060 D955CBD4 C6E1CDA4 3C9C6C96 Deciphering File Formats 223 11_574817 ch06.qxd 3/16/05 8:43 PM Page 223 With this view, you can immediately see a somewhat improved picture. The first three DWORDs are obviously some kind of 32-bit fields. The last four DWORDs are not as obvious, and seem to be some kind of a random 16-byte sequence. This is easy to tell because they do not contain text (you would have seen that in the previous dump), and they are not pointers or offsets into the file (the numbers are far too large, and some of them are not 32-bit aligned). This is a classic case where stepping into the code that deciphers this data should really simplify the process of deciphering the file format. The code that actually reads the file table and displays the file list is shown in Listing 6.6 and is actually quite simple to analyze because the fields that it reads are both printed into the screen, so it’s very easy to tell what they stand for. Let’s go back to that code sequence and see what it’s doing with this file entry. 00401A60 MOV ESI,SS:[ESP+10] 00401A64 ADD ESI,8 00401A67 MOV DWORD PTR SS:[ESP+14],1A 00401A6F NOP 00401A70 MOV EAX,DS:[ESI] 00401A72 TEST EAX,EAX 00401A74 JE SHORT cryptex.00401A9A 00401A76 MOV EDX,EAX 00401A78 SHL EDX,0A 00401A7B SUB EDX,EAX 00401A7D ADD EDX,EDX 00401A7F LEA ECX,DS:[ESI+14] 00401A82 ADD EDX,EDX 00401A84 PUSH ECX 00401A85 SHR EDX,0A This sequence starts out by loading ESI with the newly decrypted block’s starting address, adding 8 to that, and reading a 32-bit member at that address into EAX. If you go back to the previous memory dump, you’ll see that the third DWORD contains 00000001. At this point, the code confirms that EAX is nonzero, and proceeds to perform an interesting series of arithmetic opera- tions on it. First, EDX is shifted left by 0xA (10) bits, then the original value (from EAX) is subtracted from the result. At that point, the value of EDX is added to itself (which is the equivalent of multiplying it by two). This operation is performed again in 00401A82, and is followed by a right-shift of 0xA (10) bits. Now let’s go over these operations step by step and try to determine their purpose. 1. EDX is shifted left by 10, which is equivalent to edx = edx × 1,024. 2. The original number at EAX is subtracted from EDX. This means that instead of 1,024, you have essentially performed edx = edx × 1,024 – edx, which is the equivalent of edx = edx × 1,023. 224 Chapter 6 11_574817 ch06.qxd 3/16/05 8:43 PM Page 224 3. EDX is then added to itself, twice. This is equivalent of edx = edx × 4, which means that so far you’ve essentially calculated edx = edx × 4,092. 4. Finally, EDX is shifted back right by 10 bits, which is the equivalent of dividing by 1,024. The final formula is edx = edx × 4092 ÷ 1024. You might be wondering why Cryptex didn’t just use the MUL instruction to multiply EDX by 4,092 and then apply the DIV instruction to divide the result by 1,024. The answer is that such code would run far more slowly than the one we’ve just analyzed. MUL and DIV are both relatively slow instructions, whereas ADD, SUB, and the shifting instructions are much faster. It is important to note that this sequence reveals an interesting fact about Cryptex: It was most likely compiled using some kind of an optimize-for-fast-code switch, rather than with an optimize-for-small-code switch. That’s because using the direct arithmetic instructions for division and multiplication would have produced smaller, yet slower, code. The compiler was clearly aiming at the generation of high-performance code, even at the cost of a somewhat larger executable. The result of this little arithmetic sequence goes right into the printf call that prints the current file entry. This is quite illuminating because it tells you exactly what Cryptex was trying to calculate in the preceding arithmetic sequence: the file size. In fact, it is quite obvious that because the file size is printed in kilobytes, the final division by 1,024 simply converts the file size from bytes to kilobytes. The question now is, what was that original number and why was Cryptex multiplying it by 4,092? Well, it would seem that the file size is maintained by using some kind of fixed block size, which is probably somehow related to the cluster you saw earlier while decrypting the buffer. The problem is that the cluster you were dealing with earlier was 4,104 bytes long, and here you’re dealing with clusters that are only 4,092 bytes long. The difference is not clear at this point. The original number of clusters that you multiplied was taken from offset +8 in the current file entry structure, so you know that offset +8 contains the file size in clusters. This raises the question of where does Cryptex store the actual file size? It would not be possible to accurately recover encrypted files without cre- ating them with the exact size they had originally. Therefore Cryptex must also maintain the accurate file size somewhere in the archive file. Other than the file size, the printf call also takes the file name, which is easily obtained by taking the address of offset +14 from ESI. Keep in mind that ESI was incremented by 8 earlier, so this is actually offset +1C from the original data structure, which matches what you saw in our data dump, where the string started at offset +1C. After printing the file name and size, the program loops back to print the next entry. To reach the next item, Cryptex increments ESI by 0x98 bytes (152 in decimal), which is clearly the length of each entry. This indicates that there is a fixed number of characters reserved for each file name. Since you know Deciphering File Formats 225 11_574817 ch06.qxd 3/16/05 8:43 PM Page 225 that the string starts at offset +14 in the structure, you can assume that there aren’t any additional data entries after it in the structure, which would mean that the maximum length of a file name in Cryptex is 152 – 20, or 132 bytes. Once this loop ends, an interesting thing takes place. The first member in the buffer you read and decrypted earlier is tested, and if it is nonzero, Cryptex calls the function at 00401030, the function from Listing 6.7 that reads and decrypts a data chunk that we analyzed earlier. The second parameter, which is used as a kind of cluster number (remember how the function multiplies that number by 4104?), is taken directly from that first member. Clearly the idea here is to read and decrypt another chunk of data and scan it for files. It looks likes the file list can span an arbitrary number clusters and is essentially implemented using a sort of cluster linked list. This brings up one question: Is the first cluster hard-coded to number one? Let’s take a look at the code that made the initial call to read the first file-list cluster, from Listing 6.6. 00401A1E MOV EDX,DS:[406064] 00401A24 PUSH ECX 00401A25 PUSH EDX 00401A26 PUSH ESI 00401A27 CALL cryptex.00401030 The first-cluster index is taken from a global variable with a familiar address. It turns out that 00406064 is a part of the Cryptex header loaded into 00406058 just a few lines earlier. So, it looks like offset +0C in the Cryptex header contains the index of the first cluster in the file table. Going back to Listing 6.7, after 00401030 returns, ESI is tested for a nonzero value again (even though it has already been tested and its value couldn’t have been changed), and if it is nonzero Cryptex loops back into the code that reads the file table. You now know that the first member in these file table clusters is the next cluster element that tells Cryptex which cluster con- tains the following file table entries, if any. Because the size of each file entry is fixed, there must also be a fixed number of entries in each cluster. Since a local variable at [ESP+14] is used for counting the remaining number of items in the current cluster, you easily find the instruction at 00401A67, which initial- izes this variable to 0x1A (26 in decimal), so you know that each cluster can contain up to 26 file entries. Finally, it is important to pay attention to three lines in Listing 6.6 that we’ve so far ignored. 00401A70 MOV EAX,DS:[ESI] 00401A72 TEST EAX,EAX 00401A74 JE SHORT cryptex.00401A9A It appears that a file entry must have a nonzero value in its offset +8 in order for Cryptex to actually pay attention to the entry. As we’ve recently established, 226 Chapter 6 11_574817 ch06.qxd 3/16/05 8:43 PM Page 226 offset +8 contains the file size in clusters, so Cryptex is essentially checking for a nonzero file size. The fact that Cryptex supports skipping file entries indicates that it allows for holesin its file list, so when a file is deleted Cryptex simply marks its entry as deleted and doesn’t have to start copying any entries. When deleted entries are encountered they are simply ignored, as you can see here. This is exactly the type of thing you probably wouldn’t see in a robust com- mercial security product. By not erasing these data blocks, Cryptex creates a slight security risk. Sure, the “deleted” clusters are probably still encrypted (they couldn’t be in plain text because Cryptex isn’t ever supposed to insert plaintext data into the archives!), but they might contain sensitive information. Suppose that you used Cryptex to send files to someone who had the password to your archive. Because deleted files might still be in the archive, you might actually be sending that person additional files you thought you had deleted! Dumping the Directory Layout So, what would you have to do in order to actually dump the file list in a Cryp- tex archive? It’s actually not that complicated. The following steps must be taken in order to correctly dump the list of files inside a Cryptex archive: 1. Initialize the Crypto API and open the archive file. 2. Verify the 8-byte header signature. 3. Calculate an SHA hash out of the typed password, and calculate an MD5 hash out of that. 4. Verify that the calculated MD5 hash matches the stored MD5 hash from the Cryptex header (at offset +18). 5. Produce a 3DES key using the SHA hash object. 6. Read the first file list cluster (whose index is stored in offset +0C in the Cryptex header) in the same manner as it is read in Cryptex (reading 4,104 bytes and decrypting them using our 3DES key). 7. Loop through those 152-bytes long entries and dump each entry’s name if its offset +8 (which is the file size in clusters) is nonzero. 8. Proceed to read and decrypt additional file-list clusters if they are present. List any entries within those clusters. The actual code that implements the preceding sequence is relatively straightforward to implement. If you’d like to see what it looks like, it is avail- able on this book’s Web site at www.wiley.com/go/eeilam. Deciphering File Formats 227 11_574817 ch06.qxd 3/16/05 8:43 PM Page 227 The File Extraction Process Cryptex would not be worth much without having the ability to decrypt and extract files from its encrypted archive files. This is done using the x com- mand, which simply creates a file with the same name as the original that was encoded (minus the file’s path) and decrypts the original data into it. Revers- ing the extraction process should provide you with a clearer view of the file list data layout and on how files are actually stored within archive files. The rather longish Listing 6.8 contains the Cryptex file extraction routine. 00401BB0 SUB ESP,70 00401BB3 MOV EAX,DS:[405020] 00401BB8 PUSH EBX 00401BB9 PUSH EDI 00401BBA MOV EDI,SS:[ESP+84] 00401BC1 PUSH 0 00401BC3 MOV SS:[ESP+78],EAX 00401BC7 MOV EAX,SS:[ESP+80] 00401BCE PUSH 0 00401BD0 PUSH EAX 00401BD1 PUSH EDI 00401BD2 CALL cryptex.00401670 00401BD7 MOV EDX,DS:[405048] 00401BDD ADD ESP,10 00401BE0 LEA ECX,SS:[ESP+14] 00401BE4 PUSH ECX 00401BE5 PUSH 0 00401BE7 PUSH 0 00401BE9 PUSH 8003 00401BEE PUSH EDX 00401BEF MOV EBX,EAX 00401BF1 CALL DS:[<&ADVAPI32.CryptCreateHash>] 00401BF7 TEST EAX,EAX 00401BF9 JNZ SHORT cryptex.00401C11 00401BFB PUSH cryptex.00403284 ; /format = “Unable to verify the file’s hash value!” 00401C00 CALL DS:[<&MSVCR71.printf>] 00401C06 ADD ESP,4 00401C09 PUSH 1 ; /status = 1 00401C0B CALL DS:[<&MSVCR71.exit>] 00401C11 PUSH EBP 00401C12 PUSH ESI 00401C13 PUSH 0 ; /Origin = FILE_BEGIN 00401C15 PUSH 0 ; |pOffsetHi = NULL 00401C17 PUSH 0 ; |OffsetLo = 0 00401C19 PUSH EBX ; |hFile 00401C1A CALL DS:[<&KERNEL32.SetFilePointer>] Listing 6.8 A disassembly of Cryptex’s file decryption and extraction routine. 228 Chapter 6 11_574817 ch06.qxd 3/16/05 8:43 PM Page 228 [...]... MOV ECX,DS:[4 050 50] PUSH EAX PUSH ECX PUSH EBX Listing 6.8 (continued) 231 232 Chapter 6 00401DF8 00401DFD 00401E00 00401E 05 00401E09 00401E0A 00401E0B 00401E0D 00401E11 00401E17 00401E18 00401E19 00401E1F 00401E21 00401E27 00401E2D 00401E33 00401E39 00401E3F 00401E42 00401E 45 00401E4A 00401E4C 00401E51 00401E53 00401E 55 00401E59 00401E5D 00401E61 00401E66 00401E69 00401E6D 00401E71 00401E 75 00401E7A... file list is made up of one or more clusters, and each cluster contains 26 file entries Figure 6.3 illustrates what is known about a single file entry Cryptex File Header Structure Signature1 () Offset +00 Signature2 () Offset +04 Unknown Offset +08 First File-List Cluster Offset +0C Unknown Offset +10 Unknown Offset +14 Offset +18 Offset +1C Password Password Hash ssword Offset +20 Offset +24 Figure... Cluster Layout Entry #0 Individual Cryptex File Entry Structure Entry #2 (EMPTY) Entry # 25 Next Cluster Index Offset +00 Fileís First Cluster Index Entry #1 Offset +04 File Size in Clusters Offset +08 Offset +0C Offset +10 File MD5 Hash Offset +14 Offset +18 File Name String Offset +1C Figure 6.3 The format of a Cryptex file entry A Cryptex file list table supports holes, which are unused entries... EAX,DS:[4 050 50] PUSH 0 PUSH EAX MOV EAX,SS:[ESP+24] PUSH cryptex.004 050 54 PUSH EAX CALL DS:[] TEST EAX,EAX JE cryptex.00401EEE CMP EDI,1 MOV EAX,0FFC JA SHORT cryptex.00401DCB MOV EAX,DS:[4 050 50] MOV EDX,SS:[ESP+14] PUSH 0 ; /pOverlapped = NULL LEA ECX,SS:[ESP+2C] ; | PUSH ECX ; |pBytesWritten PUSH EAX ; |nBytesToWrite PUSH cryptex.004 050 54 ; |Buffer = cryptex.004 050 54 PUSH EDX... MOV EAX,DS:[EAX+4] First of all, let’s inspect what is obviously an optimized arithmetic sequence of some sort in the beginning of this sequence It can be slightly confusing because of the use of the LEA instruction, but LEA doesn’t have to deal with addresses The LEA at 004018 85 is essentially multiplying ESI by 5 and storing the result in EAX If you go back to the beginning of this function, it is... that does flow in and out of the computer and the different levels of access rights granted to different users, but these are not as relevant to our current discussion So how does reversing relate to maintaining control of the flow of information on a system? The idea is that whenever you install any kind of software product, you are essentially entrusting your computer and all of the data on it to that... sequentially within the archive Because of this, Cryptex always reads the next cluster index from 004 050 50 and passes that to 00401030 when reading the next cluster 004 050 50 is the beginning of the currently active cluster buffer This indicates that, just like in the file list, the first DWORD in a cluster contains the next cluster index in the current chain One interesting aspect of this design is revealed in... means in the context of this book I think security 243 244 Chapter 7 can be defined as having control of the flow of information on a system This control means that your files stay inside your computer and out of the hands of nosy intruders, while malicious code stays outside of your computer Needless to say, there are many other aspects to computer security such as the encryption of information that... 00401C29 00401C2E 00401C2F 00401C 35 00401C3C 00401C3E 00401C3F 00401C43 00401C47 00401C48 00401C4C 00401C50 00401C51 00401C58 00401C60 00401C61 00401C62 00401C6A 00401C6E 00401C76 00401C7D 00401C82 00401C86 00401C88 00401C89 00401C8D 00401C93 00401C 95 00401C97 00401C9A 00401C9C 00401C9E 00401CA0 00401CA3 00401CA5 00401CA6 00401CAA 00401CAC 00401CAF 00401CB1 00401CB3 00401CB5 00401CB7 00401CBB PUSH 0 ; LEA... EBP,DS:[] PUSH EAX PUSH cryptex.00403308 ; ASCII “Extracting “%.35s” - “ MOVSS SS:[ESP+24],XMM0 FSTP DWORD PTR SS:[ESP+34] CALL EBP Listing 6.8 (continued) ; ; ; ; ; ; Deciphering File Formats 00401D59 00401D5C 00401D5E 00401D64 00401D6A 00401D70 00401D76 00401D7A 00401D7B 00401D7C 00401D7E 00401D82 00401D 85 00401D88 00401D8D 00401D8F 00401D92 00401D 95 00401D9A 00401D9C 00401DA1 00401DA3 00401DA4 00401DA8 00401DAD . Formats 221 11 _57 4817 ch06.qxd 3/16/ 05 8:43 PM Page 221 00401 051 LEA EDX,SS:[ESP+18] ; 00401 055 PUSH EDX ; pOffsetHi 00401 056 PUSH EAX ; OffsetLo 00401 057 PUSH ESI ; hFile 00401 058 CALL DS:[<&KERNEL32.SetFilePointer>]. as a sequence of 32-bit hexadecimal numbers: 004 050 50 00000000 00000002 00000001 0CDDEB52 004 050 60 D 955 CBD4 C6E1CDA4 3C9C6C96 Deciphering File Formats 223 11 _57 4817 ch06.qxd 3/16/ 05 8:43 PM Page. contents of the decrypted block I obtained while trying to list the files in the Test1.crx archive created earlier. 004 050 50 00 00 00 00 02 00 00 00 004 050 58 01 00 00 00 52 EB DD 0C Rë_. 004 050 60

Ngày đăng: 14/08/2014, 11:21

Xem thêm: reversing secrets of reverse engineering phần 5 doc

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN