greets hm some reversing today. As you all know, NotePad is the best HMTL editor out there (uhm perhaps uedit is better but i dont like it). The only thing Iam missing is a small button that enables me to check my work without saving it....... Tools you need: * sice (uhm you dont *need* it) * hiew * procdump (same as sice here) * MS NotePad (73.728 bytes long - check yours so offsets will match) Well ill not explain everything here. The APIs will be explained but you should know how to ride a hexeditor... Ok we have to add a new item to the menu. I used Borland Resource Workshop. Open a new project - notepad.exe. Doubleclick on Menu 1 and add a new item "Try it". This will be the item which will raise our code. Remember the Item ID(it should be 101(decimal!) for standard). Save your work and close brw. You should have a new menu item when you start your notepad. Well, our new menu item wont do anything up to now, because within the message handle of notepad there is no appropriate code to a menu item 101. Before we add this code lets think about *what* we want to add. When the menu item is clicked, notepad should save the written content. It should not be necessary to save the html by hand - our code should do that. To get the content we use WM_GETTEXT, sent with SendMessage. To open and handle the temp file we use createfile, writefile and closehandle. We also need localAlloc and localfree to create an array for our text. To start Internet Explorer we will use createprocess. Lets take a look at SendMessage: LRESULT SendMessage( HWND hWnd, // handle of destination window UINT Msg, // message to send WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); Hmm we need the handle of the edit window of notepad. Where could we get this? Thats an easy task. Fire up sice and set a breakpoint on CreateWindowExA: bpx createwindowexa do "d @(esp+8)". Sice should break 2 times while loading notepad. The first time - as we can see in our data window - notepad creates the main window. The second time the edit window is created. We need the handle to this window. Leave the API with F12: * Possible StringData Ref from Code Obj ->"Edit" | :00402D9A 6854104000 push 00401054 :00402D9F 6800020000 push 00000200 * Reference To: USER32.CreateWindowExA, Ord:005Ah | :00402DA4 FF1534644000 Call dword ptr [00406434] :00402DAA A304504000 mov dword ptr [00405004], eax :00402DAF 3BC7 cmp eax, edi :00402DB1 0F8466030000 je 0040311D Hm see line 402DAA. Thats all we need. After the window is created notepad stores the handle at 405004 - great! Now we can send our message to this window - WM_GETTEXT. But first we need a place to store the text we will get. Therefore we create an array with LocalAlloc: HLOCAL LocalAlloc( UINT uFlags, // allocation attributes UINT uBytes // number of bytes to allocate ); For uflags we can set lmem_fixed but we also need the length. An easy task again. We send WM_GETTEXTLENGTH to the edit window and thats it :) We created the array and copied the text into it. Now we've to save this to a .html file. We open a new file with CreateFileA: HANDLE CreateFile( LPCTSTR lpFileName, // pointer to name of the file DWORD dwDesiredAccess, // access (read-write) mode DWORD dwShareMode, // share mode LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes DWORD dwCreationDistribution, // how to create DWORD dwFlagsAndAttributes, // file attributes HANDLE hTemplateFile // handle to file with attributes to copy ); Thats nothing fancy we know every of these parameters. We can store the name of the file in the .data cave, everything else is clear. Lets take a look at WriteFile: BOOL WriteFile( HANDLE hFile, // handle to file to write to LPCVOID lpBuffer, // pointer to data to write to file DWORD nNumberOfBytesToWrite, // number of bytes to write LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O ); Nothing difficult here as well. lpOverlapped is null, nNumberOfBytesToWrite is the result of WM_GetTextLength. We close the file with CloseHandle.... Ok now we have got our .html - now lets load IE. As said we use CreateProcess: BOOL CreateProcess( LPCTSTR lpApplicationName, // pointer to name of executable module LPTSTR lpCommandLine, // pointer to command line string LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes BOOL bInheritHandles, // handle inheritance flag DWORD dwCreationFlags, // creation flags LPVOID lpEnvironment, // pointer to new environment block LPCTSTR lpCurrentDirectory, // pointer to current directory name LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION ); (pasting win32.hlp makes my tutor looking much bigger :x) We will hardcode lpApplicationName - looking up IE's path in registry is not part of this tutor's topic. lpCommandLine is what we need to make IE loading our html file at startup. Everything else is unimportend. Hmmm thats quite a bunch of code. I fear we will run of space within our .text cave. We could change the characteristics of .data so we can execute code there but the real problem is that with adding even more functions, our code will get much more complicated. To prevent this we will write a DLL. The code within the .text cave will load, handle and unload the DLL only - the functions remain in die DLL, where the code can be as big as it wants or has to be. I wont go into details how to write your own DLL now - take a look at htmlpad.asm that comes with this tutor. The only parameter, pushed into the function, is edithandle. This is the handle to the edit window of notepad(as the name says :)). Ok now we got our DLL, lets see how to load it. First of all we need to load the dll using LoadLibrary. The parameter, passed to LoadLibrary is the name of the DLL - cripsy :) Then we've to use GetProcAddress to get the address of our function. After that we can push the window handle and call the function. Finaly we close the DLL with FreeLibrary. First lets inject the parameters - the name of the dll and the name of the function - into the .data cave. The Virtual Size is 84Ch, the Raw Offset is 5000h. Use ProcDump or a hexeditor to find out these values. Hexedit notepad.exe and goto 5000h+84ch = 584ch. Write "htmlpad.dll" and "newfunction" there. Dont forget the zero terminator after "htmlpad.dll". The offset of the dll's name is now 40584ch and for the function's name 405858h. Remember that the handle to the edit window is stored at 405004h. Well, our code should now look like this: push 0040584c call LoadLibrary push eax push 00405858 push eax call GetProcAddress push [405004] call eax call FreeLibrary As seen we use LoadLibrary, GetProcAdress and FreeLibrary. NotePad doesnt import these functions but we need them for our code. This is how to solve this problem: We know the offsets of many other imports from kernel32 and therefore we know their offsets while runtime. Disasm kernel32 to find out the offset of LoadLibraryA. For me its 0BFF912EDh. *Note that these values can differ* Now search for another function, which is imported by NotePad. I chose CreateFileA but you can choose any other. The offset for cf is 0BFF77ADFh. Now comes the trick: The difference between these offsets is 1980E. While runtime we get the offset of CreateFileA. We add 1980E to this value and bang we got our LoadLibraryA. For me these are the values with the base CreateFileA: LoadLibraryA: 1980E GetProcAdress: FFFFF2CD FreeLibrary: 165C1 In notepad.exe the CreateFileA import is located at 004063c0. There the offset of CreateFileA is stored while runtime. We simply add our values to get our functions. Note that this is another advantage of using a DLL - we've to calculate three new imports only and not every import we may use. *Remember: These values WILL differ! calculate them for yourself. The exe will NOT be portable to another system* The only reliable method would be to search for the kernel32 export table in memory and get the offsets there but thats not topic of this tutorial. Now we need to find a place where we can inject our new code. When a menu item is pressed, windows sends WM_COMMAND to the window. Within sice u can find out the hex value with wmsg wm_command. Now, within notepad, set a bpx on TranslateMessage. You should break immediatly. If you break within iamapp, getright or something else just press F5 until you are in notepad. Press F12 to get back into notepad's code - you are within notepad's message handle loop. The only parameter, passed to TranslateMessage, is the address of the msg structure. Lets take a look at such a message structure: typedef struct tagMSG { // msg HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG; Ok hwnd, time, pt and lparam are unimportend. wParam holds our menu code in its low-ordered word. If our menu is pressed wParam should hold our menu code 65h, while uint holds the code for wm_command. This is the code around TranslateMessage: :0040211D 85C0 test eax, eax :0040211F 7514 jne 00402135 :00402121 8D45E4 lea eax, dword ptr [ebp-1C] :00402124 50 push eax * Reference To: USER32.TranslateMessage, Ord:025Dh | :00402125 FF1594644000 Call dword ptr [00406494] :0040212B 8D45E4 lea eax, dword ptr [ebp-1C] Ok we will replace the call at 402125h with a jmp to 404e9c - the beginning of the .text cave. Remember that we've to call translatemessage in *any* case. So open notepad.exe with hiew. Switch mode to asm and go to 2125h. Edit it and change it to jmp 4e9c. As the jmp command needs one byte less space, fill the space with a nop. The next command beginns at 40212B. After executing our code we'll have to jump back there. Here is the code in injected into the cave. Remember that eax points to the message structure. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00402125(U) | :00404E9C 668178041101 cmp word ptr [eax+04], 0111 ;is it wm_command? :00404EA2 754D jne 00404EF1 ;no? then get out of here :00404EA4 6683780865 cmp word ptr [eax+08], 0065 ;is it our menu item? :00404EA9 7546 jne 00404EF1 :00404EAB 60 pushad ;save registers * Reference To: KERNEL32.CreateFileA, Ord:0040h | :00404EAC 8B1DC0634000 mov ebx, dword ptr [004063C0] ;get import for cf :00404EB2 81C30E980100 add ebx, 0001980E ;calculate loadlibrary * Possible StringData Ref from Data Obj ->"htmlpad.dll" | :00404EB8 684C584000 push 0040584C :00404EBD FFD3 call ebx ;load dll * Reference To: KERNEL32.CreateFileA, Ord:0040h | :00404EBF 8B1DC0634000 mov ebx, dword ptr [004063C0] :00404EC5 81C3CDF2FFFF add ebx, FFFFF2CD ;calculate getprocaddress :00404ECB 50 push eax * Possible StringData Ref from Data Obj ->"newfunction" | :00404ECC 6858584000 push 00405858 :00404ED1 50 push eax :00404ED2 FFD3 call ebx ;and get the function :00404ED4 FF3504504000 push dword ptr [00405004] ;push handle of edit window :00404EDA FFD0 call eax ;TRY IT! ;) * Reference To: KERNEL32.CreateFileA, Ord:0040h | :00404EDC 8B1DC0634000 mov ebx, dword ptr [004063C0] :00404EE2 81C3C1650100 add ebx, 000165C1 ;calculate freelibrary :00404EE8 83EC04 sub esp, 00000004 ;uhm - crispy stack :( :00404EEB FFD3 call ebx ;unload library :00404EED 83EC04 sub esp, 00000004 ;crispy stack again :00404EF0 61 popad ;restore registers * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00404EA2(C), :00404EA9(C) | * Reference To: USER32.TranslateMessage, Ord:025Dh | :00404EF1 FF1594644000 Call dword ptr [00406494] :00404EF7 E92FD2FFFF jmp 0040212B ;get out of here! You should find notepad.exe in this zip file, to try out what you just learned. htmlpad.dll and source is included as well. You must calculate the offset differences for yourself in order to correctly import loadlibrary, getprocadress and freelibrary or the htmlpad.exe in this zip wont run. Perhaps you are lucky and the values match. Thats all ;) Greetings fly out to: defiler, ultraschall, KeyboardJunky, viny, Peegee, rheingold, trench, zorny, slowhand and uhm i dont know... you can contact me via knabberknusperhaus@yahoo.de or by joining #learn2crack on EFNet. (c) 00 by [Basic] all rights reversed1;