How to play patch (2) --- Improve article statement: one. This paper is practical for beginners, requiring certain assembly and system underlying knowledge. two. This article is only to let the majority of netizens will improve some basic knowledge. I will do not find out if I need readers who need this knowledge, if you are a master, or don't need this knowledge, please skip. three. Examples of this article are ordinary procedures, if there is similarity, please understand. four. This article welcomes the transfer, if it is commercial use, please contact me. http://www.zoudan.com zd_dan@263.com I don't know how to understand the content of "Basics", I have to lead everyone now, please listen to you! This time, how is it? Add a function to the program. Everyone knows that only a small amount of space and location in the executable can place our patch, which is destined to have a complicated function. Imagine, if you add a lot of assembly code in the people's program, you can only be assembly code (don't ask me why), and debug operation. Because it is running in people's operating environment, you must maintain a large number of registers, address space, stack, etc., which will be a matter of difficult and painful. Compilation can make a lot of things, but it is not universal. It is necessary to use compilation to achieve a lot of complex functions. I have made a FOLKQQ patch for everyone. In fact, the assembly code is dozens of lines, and the functions are also very simple, dozens of bytes. But this has made me suffer enough, if you are more, the ordinary people do not eat (debug running these code is very laborious, if a place is wrong, it is very heavy, and the crash will restart. Seeing this, there may be a classmate will ask, like your SE patch series, which realizes the conversion of the IP address to the specific physical address. Is it written by compilation (written this will be dead)? Of course, everyone notes have an ipsearch.dll, this is a dynamic link library, see the name, know this is about the IP address to convert to the actual address function. Yes, all conversion work is completed. He is written by VC, the program is very simple, but if you write it with complications, it is more complicated. I think I don't have perseverance to write it with a compilation, and then a byte of one instruction is knocked in the program. Oh, today, how to implement a complex function in the patch, the specific problem has been described above, the method is to bring a dynamic link library to the program, keep all the complex functions in the DLL, let the senior language go It is difficult to implement the function, leave an interface, which can be used for use. About what is DLL, I don't want to say more. Simple understanding is a library, others call it, it is complete, it is as simple as it is. Everyone can use the software to see the ipsearcher.dll I wrote (using TDUMP, or Tool Depends.exe), you can see only one function interface, called "_getaddress". Give it an IP address as a parameter, it can return the actual address of that IP address. The specific achievement is not in our discussion today. The key to the problem is how to call this dynamic link library in the program to be patched, let it add the patch service to us.
Look down, you need a classmate to have certain Win32 PE formats based on the basis of the executable of Win32 PE format (you can refer to my previous "Encrypted Research on the Executable Documents under Win95" and "Basics"). In the PE file, specify all the dynamic link libraries to be used, and which function interface to call. This information is written in a data structure called Import Table. It describes the calling address of a function interface of a dynamic link library, which is to enable the system to load the dynamic link library and relocate the interface address information for the program. Maybe everyone is a little dizzy, it doesn't matter. Let me explain Import Table with an instance. We open a PE format with TDUMP: C: /> TDUMP EXAMPLE.EXE | MoreTurbo Dump Version 5.0.16.12 Copyright (C) 1988, 2000 Inprise Corporation ........ Name RVA Size --- ---------------------- --------- exports 00000000 000,000 IMPORTS 0019CFA0 0000017CRESOURCES 00287000 00077F18 ........ # name Virtsize RVA Physize Phys Off Flags - -------- -------- ---------------------------------------------------------------------------------------------------------------------------------------------------- ---- 01 .text 00157744 00001000 00158000 00001000 60000020 [CER] 02 .rdata 0004723A 00159000 00048000 00159000 40000040 [IR] 03 .data 000E5C28 001A1000 0002A000 001A1000 C0000040 [IRW] ....... Section: ImportImportLookUpTblRVA: 0019D938Time Stamp 00000000 200000000 (Index of First Forwarder Reference) Imports from Winmm.dll (hint = 0071) Mixeropen (hint = 0065) MixerClose (hint = 006b) MixergetLineControlsa first talks about the first place where red characters appear, this is this program Import table's RVA address (what is RVA yourself to check) and length; the second red word is 1A1000, it is greater than 19cfa0, what is it, the address of the import table is in the .rdata paragraph (it seems to be used, huh, huh, huh, Write it, no matter how much it is); the third red word is the specific content of TDUMP, such as a dynamic link library called Winmm.dll, you need to call its sequence The number is a 0ach WaveoutClose function. There are many such as such a few, usually a program needs to call at least a few dynamic link libraries (kernel32.dll, user32.dll, etc.). What is the specific look in the file in the file, and the students can use the UltraEdit to open the offset of 19cfa0. Then combine the results I give the data structure and TDUMP analysis, and understand and understand. The following extracted the "Encryption Research on the Executable Documents under Win95". IDATA block starts with an image_import_descriptor array.
Every DLL that is implicitly connected by the PE file has an image_import_descriptor. In this array, there is no field indicating the number of items of the structure, but its last unit is NULL, which can be calculated by counting the number of items of the array. Image_import_descriptor's format is as follows: DWORD Characteristics This field is a pointer array of RVA offset. Each of these pointers points to an image_import_by_name structure DWORD TIMEDASTAMP time and date flag, which can be ignored. DWORD forwarderchain is a link index. There is no format in our information, and there is no such example. Dword Name The RVA address of the ASCII character ending with NULL, which contains the input DLL name, such as "kernel32.dll" or "user32.dll". PIMAGE_THUNK_DATA FIRSTTTHUNK This field is an RVA offset in the image_thunk_data federated structure. In most cases, image_thunk_data refers to a pointer to the image_import_by_name structure. If it is not a pointer, it is the serial number of this feature in the DLL. Image_import_descriptor Important Section An Input DLL name and two image_import_by_name pointer arrays. In executing files, these two pointers are parallel to each other, and they are ends with NULL. The figure below shows a graphical description of this relationship. Why does the two parallel pointer arguments point to the IMAGE_IMPORT_BY_NAME structure? The first CHARACTERISTICS is a separate item and cannot be rewritten. It is sometimes referred to as a prompt name (Hint Name Table). The second array (refers to Firstthunk) is rewritten by the PE loader. The loader iterates each pointer in the array, finds the address of the input function referred to in each image_import_by_name structure, and then the loader finds the address of the program to overwriting the image_import_by_name pointer. [Xxxxxxxx] in JMP DWORD PTR [xxxxxxxx] refers to an entry in the first thunk array. Because it is called an input address table (IMPORT Address Table). Ok, I don't know if you understand that there is no, you can take a closer look at my article on the import table, which is very detailed. Our goal is already clear, add our own DLL description to the import table, let the system load our own DLL while loading the program, and do a good repositioning, for us The patch call is prepared for the interface in the DLL. We can directly modify the Import Table, if there is enough space, we can do it. But Import Table is often a small piece of data, which can be a segment, or anywhere in the program. So IMPORT TABLE often has other data before and after, we have to add a very difficult thing (in fact, 20 bytes). That if there is a half of the data before and after, it doesn't matter, you will all move all other idle places (where you are idle, please see "basic articles").
But must remember that the fields of the PE department must be modified (the place described by the first red word), change to your own import table, of course, the length should also be modified (usually a DLL is one, One is 20 bytes). The most important and most critical is to construct an IMPORT TABLE. (Drinking the water, slightly, etc.) The specific data structure and description of the entry have been described above. Use UltraEdit to change the binary, just like a knife to the patient, be careful. To remember, every bit of each data is like the flesh of the patient. Before the knife, there must be confidence before the knife, must be grasped, cautious, carefully, and stabilize. . . . Forget it, I am nervous, I still explain it. (On a WC, I am sorry), I will talk to everyone. Let's take a look at the 16-encyclosure image of a practical PE. Take that program as an example, we already know its IMPORT TABLE starting RVA address (0019cfa0), open the program with UltraEdit, press That Goto button, then enter the address "0x19cfa0" Enter. This way you will look at the image of the file on the file. (As shown below) You can see this executable from 19CFA0 to 19D11b total 17c bytes of Import Table, where the last 20 bytes are empty tables, which indicates the end of this import Table. It can be seen that there is still a lot of unknown data after the end of the Import Table, which gives us difficulties. What should I do, I have already mentioned that I have been in other places. How to move? 1. First look at the place, we found 001A0250, it is in. RDATA and .DATA, you can use UltraEdit to find each segment, often have space. (How to find a gap, please refer to "Basics") 2. Move the UltraEdit cursor to the address 19cfa0 to 19d11f (0x180h bytes), then press CTRL-C to copy. Then move the cursor to 1A0250, select the blank 0x180h by one byte (if you don't pick it up, it is inserted), press Ctrl-V. This way we copy the previous Import Table to the new place (formerly import Table 19CFA0 without deleting). 3. After copying, you also need to point the first site of the Import Table in the PE file head Dir Table to a new place. The specific approach is that in the file head looks for the number A0 CF 19 00 (which is 19cfa0), change it to 50 02 1A 00 (1A0250), and then followed by the length of the two of the IMPORT TABLE, before 17ch, now changed to 17CH 14H = 190H.
(14H = 20, this is a term "long), let us check the file with TDUMP: Name RVA Size --------------------- --- -------- Exports 00000000 00000000Imports 001A0250 00000190 ....... Section: ImportImportLookUpTblRVA: 0019D938Time Stamp: 00000000Forwarder Chain: 00000000 (index of first forwarder reference) Imports from WINMM.dll (hint = 0071 ) Mixeropen (hint = 0065) MixerClose (hint = 006b) MixergetLineControlsa's first red word means that we have changed the first site of Import Table to 1A0250. The second red word means that the new import table is reliable. Ok, the most important thing is the most exciting time, let us truly add an entry for this new import Table, add a form must be based on the IMPORT TABLE structure, the process is the process of entering the process. Enter some 16-in-order and strings. Below is a post-entered screen cut map, I will combine the picture as everyone's explanation. Ok, everyone has seen, this is the import table after adding a good item, where 1A0250 to 1A03B8 is exactly the same as previous Import Table. The previous import table is after 1A03B8 is a 20-byte full end. 1A03B9 to 1A03CC is the entry we add, and 20 bytes behind are new endors. Then 16 bytes, followed by DLL information. Let me tell everyone every field of the new item. 1A03B9 begins, the first DWORD is 1A0410. Address 1A0410 is a point of 1A03F0, 1A03F0, which is a description of a DLL interface (please refer to the information yourself). You can see that 01 00 (0001) is the serial number of the _getaddress function in the DLL (only one function interface in ipsearchrcher.dll, the serial number is 1), then a string "_Getaddress" ending with 0 is the name of the function. . The second third DWORD of the entry is TimeStamp and the backward pointer chain, regardless of (only one function, so the pointer chain is 0, indicating the end). The fourth DWORD is 1A03E0, which points to the file name of the DLL file, and the legend is "ipsearchcher.dll", of course, it also needs to end with 0. The fifth DWORD is 1A0418, which is a value in the legend, in fact, no matter. Because this address is the specific address of the function interface that the system is filled in after the DLL is loaded. Our patch is to call the address in this address to call the _getaddress this function. How do you access it? The program load address is 40000h, so the address is after loading is 40000h 1A0418H = 5A0418H. Our patches can be called using Call DWORD PTR [5A0418]. Oh, modifying that the work of Import Table has ended. I am talking hard, I don't know if you understand, don't say that I have not taken care of everyone's feelings! Yes, there is a very important thing.