home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Iczelion / w32_01.txt < prev    next >
Text File  |  2000-05-25  |  13KB  |  405 lines

  1.                            -          
  2.               -----=========-----
  3.       -------==========================================----------
  4. ---------===_masta_'s Tutorial on Win32 ASM Coding Part 1===----------
  5.       -------==========================================----------
  6.  
  7.                  --==INTR0==--
  8.  
  9.                 -[Hi!]-
  10.  
  11. After the part 0 I got some mail saying that it was a good idea to do 
  12. a windows-based revival of the "old art" of assembly language 
  13. programming. We all know that DOS is about to die (not many (if any) 
  14. of us are happy about that), but unfortunately we can't change this 
  15. fact.
  16.  
  17.                 --==WHAT IS NEEDED?==--
  18.  
  19.  
  20.         1. Texteditor
  21.         2. TASM 5.0, complete with libs, etc.
  22.         3. Win32-API-Reference (Win32.HLP)
  23.  
  24. I assume you have basic knowledge of assemly, althought most of the 
  25. stuff is easy to grasp.
  26.  
  27.              --==SENSE OF THIS PROJECT==--
  28.  
  29. We want to code a "generic patcher" which is also known as a 
  30. "Search-and-Destroy-Patcher".
  31. Since many people may not know what to expect from a Generic-Patcher,
  32. I want to explain it shortly. It is a patcher, which is not only able 
  33. to patch a certain version of a program, but future versions also, if 
  34. they are nearly the same. This is done by searching for a certain 
  35. byte-pattern (and writing a new one) and not by patching some offset, 
  36. which makes this kind more universal to use.
  37. Since most likely the protection-scheme is not changed by the coder,
  38. this bytes of this routine may have another offset-address in the 
  39. newer (older) version, but the bytes will be the same. 
  40. That's the trick =).
  41.  
  42.                --==LET'S GO!==--
  43.  
  44.  
  45. OK, first we think about the main structure of our program, then we 
  46. think about which functions we use and last but not least, we write 
  47. the program.
  48.  
  49. 1. Intro           - Little intro, presented in a MessageBox
  50. 2. Open File       - Set file-handle. If file not exist -> MessageBox
  51. 3. Get Filesize
  52. 4. Allocate memory - Allocate memory equal to the filesize. 
  53.              If error -> MessageBox
  54. 5. Read File       - copy complete file into allocated memory
  55. 6. Search Bytes    - Determination of the offset of the bytepattern. 
  56.              If errors -> MessageBox
  57. 7. Set Filepointer
  58.    to offset
  59. 8. Overwrite File  - Patch of the file. Success -> MessageBox
  60.    with new bytes
  61. 9. Close File      - Cleanup!
  62.    Deallocate Mem
  63.    Quit
  64.  
  65.               --==API-FUNCTIONS==--
  66.  
  67.  
  68. - All messages will be presented by a messagebox, i.e. 'MessageBoxA'.
  69.  
  70. - For opening the file we will use the 'CreateFileA'-function, which 
  71.   is more complex than the 'OpenFile, but also more flexible to use.
  72.  
  73. - To close we will use 'CloseHandle'.
  74.  
  75. - The filesize we get via 'GetFileSize'
  76.  
  77. - We allocate the mem with the help of 'GlobalAlloc'; set it free 
  78.   again with 'GlobalFree'
  79.  
  80. - Logically we read the file with 'ReadFile' and write it with 
  81.   'WriteFile'
  82.  
  83. - The Filepointer can be set with 'SetFilePointer'
  84.  
  85. - To quit we use 'ExitProcess'
  86.  
  87.  
  88.                   --==THE BYTE SEARCH==--
  89.  
  90.  
  91. This is the heart of our patcher. With the help of this little routine
  92. the target-file is searched for a byte pattern, which will be changed 
  93. later. I will just explain it shortly, because the most you can get 
  94. out of the code.
  95. OK, we first load the size of the file (the alloc. memory) into ECX to
  96. set a value for the "REPNZ"-command; also the first byte of the search-
  97. pattern is written into AL and ESI is set to the address of the 
  98. original values.
  99. With 'REPNZ SCASB' the value of AL is compared to the value of the 
  100. memory address, which EDI points to (EDI is incremented by 1). The 
  101. 'REPNZ'-command repeats the following 'SCASB' as long as either ECX=0 
  102. or the compared values are equal (FL Z=1).
  103. If the values are equal ECX is loaded with the length of the patch, 
  104. EDI is decremented by 1, because the 'SCASB' already counted one byte 
  105. ahead.
  106. The following 'REPZ CMPSB' repeats 'CMPSB' (compares the address of 
  107. [ESI] with the one of [EDI]) as long as either ECX=0 or the value 
  108. differs.
  109.  
  110.  
  111.               --==THE PATCH ITSELF==--
  112.  
  113.  
  114. Now quickly some stuff about the patch routine itself.
  115. First the offset is calculated by incrementing ECX (byte-counter) by 1 
  116. and this value we subtract from the total filesize:
  117.  
  118. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  119. (FILESIZE) - (BYTES UNTIL THE END OF FILE) = ACTUAL OFFSET
  120. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  121.  
  122. This value is put on the stack, as well as the file-handle to later 
  123. CALL the function 'SetFilePointer' to set the filepointer to our offset.
  124. After that the buffer for the written bytes (bwrite), the length of the 
  125. patch, the offset of the new bytes and the file-handle is PUSHed and 
  126. the API-function 'WriteFile' is CALLed.
  127.  
  128.                  --==THE SOURCE==--
  129.  
  130.  
  131. Maybe a bit complex, but I guess still easy to understand =) ...
  132.  
  133. ;-------------------------------===START===---------------------------
  134.         ; set a couple of options for the assembler
  135. .386P
  136. Locals
  137. jumps
  138.  
  139. .Model Flat ,StdCall
  140. mb_ok            equ 0
  141. hWnd            equ 0
  142. FILE_ATTRIBUTE_NORMAL    equ 080h
  143. OPEN_EXISTING        equ 3
  144. GENERIC_READ        equ 80000000h
  145. GENERIC_WRITE        equ 40000000h
  146.  
  147.  
  148. ; --==declaration of all used API-functions==--
  149.  
  150. extrn     ExitProcess      : PROC ;procedure to end the program
  151. extrn     MessageBoxA      : PROC ;procedure to show a MessageBox
  152. extrn     CreateFileA      : PROC ;   " ...  to open a file
  153. extrn      ReadFile        : PROC ;read a block of a file
  154. extrn      WriteFile       : PROC ;write a block into a file 
  155. extrn      CloseHandle       : PROC ;close file
  156. extrn     GetFileSize       : PROC ;get the filesize
  157. extrn      GlobalAlloc       : PROC ;allocate memory
  158. extrn      GlobalFree       : PROC ;set (free) memory
  159. extrn     SetFilePointer   : PROC ;set the filepointer
  160.  
  161. ; --==here begins our Data==--
  162.  
  163. .Data
  164.  
  165. caption  db "_masta_'s essay on Win32-ASM-Coding, part 1",0 
  166.     
  167.                    ;captionstring, 0-terminated
  168.  
  169. text     db "Hi, nice to CU again",13,10 
  170.      db "This tut will describe you how to make",13,10
  171.      db "Win32-ASM Search and Destroy patchers",0
  172.                                 
  173.                    ;introtext, 0-terminated
  174.  
  175. err_cap  db "ERROR",0           ;caption for errormessage
  176.  
  177. openerr     db "Error on opening File",0        ;errortext opening file
  178. memerr     db "Error on allocating memory",0  ;errortext alloc. memory
  179. byterr   db "File is here, but i can't find the original bytes",0
  180.                         
  181.                         ;error while bytesearch
  182.  
  183. readycap db "Ready",0                ;caption for 'done'
  184.  
  185. readytxt db "Ok, file is patched",0        ;text for 'done'
  186.  
  187. file     db "make.old",0        ;what file we want to patch?
  188. org_val  db "Xmas'97"        ;original values
  189. new_val  db "_masta_"        ;new values
  190. len     equ $-new_val        ;how many values (length)
  191.                 ;org_val and new_val must be equal
  192.  
  193. fhandle  dd  ?            ;variable for the filehandle
  194. fsize     dd  ?            ;variable for the filesize
  195. memptr     dd  ?            ;pointer to allocated memory
  196. bread    dd  ?            ;number of read bytes
  197. bwrite   dd  ?            ;number of written bytes
  198.  
  199. ;--==and here we start with our code==--
  200.  
  201. .Code
  202. Main:
  203.         push mb_ok              ;PUSH value for 'uType'
  204.         push offset caption     ;PUSH pointer to caption 
  205.         push offset text        ;PUSH pointer to Text
  206.         push hWnd               ;PUSH Masterhandle
  207.         call MessageBoxA        ;CALL MessageBoxA
  208.  
  209.         push 0                    ;for Win95 always 0
  210.         push FILE_ATTRIBUTE_NORMAL        ;standard Fileattributes
  211.         push OPEN_EXISTING            ;open existing file
  212.         push 0                    ;no Security-attributes
  213.         push 0                    ;disable Share-Mode
  214.         push GENERIC_READ + GENERIC_WRITE    ;read- and writeaccess
  215.         push offset file            ;offset of the filename
  216.         Call CreateFileA            ;open file
  217.     mov  fhandle,eax            ;save filehandle
  218.     cmp  eax,0FFFFFFFFh            ;if eax=FFFFFFFF then 
  219.                          error
  220.     jnz  file_is_here
  221.  
  222.         push mb_ok              
  223.         push offset err_cap     
  224.         push offset openerr     
  225.         push hWnd               
  226.         call MessageBoxA        ; showerrormessage
  227.     jmp  end_        ; jump to end
  228.  
  229. file_is_here:            ;file is there, so go on
  230.  
  231.     push 0            ;can be 0, if the filesize is less 
  232.                      then 4,3 GB :)
  233.     push fhandle        ;PUSH filehandle
  234.     Call GetFileSize    ;get the filesize
  235.     mov  fsize,eax        ;save the filesize
  236.  
  237.     push fsize        ;PUSH filesize=size of the buffer
  238.     push 0            ;0=GMEM_FIXED -> fixed memory-area
  239.     Call GlobalAlloc    ;allocate as much as memory as filesize 
  240.     mov  memptr,eax        ;save pointer to memory-area
  241.  
  242.     cmp  eax,0        ;if eax=0, then there were errors
  243.     jnz  mem_ok
  244.  
  245.         push mb_ok              
  246.         push offset err_cap     
  247.         push offset memerr      
  248.         push hWnd               
  249.     call MessageBoxA
  250.         jmp  end_kill_handle    ;end program, close file b4
  251.  
  252. mem_ok:                ;memory is allocated -> next step
  253.  
  254.     push 0            ;set to 0 in most cases
  255.     push offset bread    ;pointer to number of read bytes
  256.     push fsize        ;read how many bytes?, 
  257.                  fsize=whole file
  258.     push memptr        ;save where? ->allocated memory
  259.     push fhandle        ;filehandle
  260.     Call ReadFile        ;read file!
  261.  
  262. read_ok:
  263.  
  264.         mov  edi,memptr        ;set EDI to memory-area
  265.         mov  ecx,fsize        ;set ECX (for repnz) to filesize
  266.         mov  esi,offset org_val ;set ESI to the string to find
  267.         mov  al, byte ptr [esi] ;load AL with the first byte
  268.  
  269. loop_:
  270.         repnz scasb        ;repeat until ECX=0 or AL equals
  271.                 ;the value of the byte [EDI], EDI is 
  272.                 ;incremented by 1 every run
  273.         cmp  ecx,0        ;If ECX=0, nothing is found
  274.         jz   not_found
  275.        
  276.  
  277. here_is_something:        ;found matching byte
  278.  
  279.         push ecx        ;save register
  280.         push edi
  281.         push esi
  282.     dec  edi        ;EDI-1, cos REPNZ SCASB is one step too far
  283.         mov  ecx,len        ;ECX=length of the patch
  284.         repz cmpsb        ;repeat until the values in the memory of 
  285.                 ;[EDI] and [ESI] are different,
  286.                 ;or ecx=0
  287.         cmp  ecx,0        ;If ecx=0, then the org_val is in memory
  288.         jz   patch        ;->jump to patcher
  289.  
  290. not_that:            ;it is not yet here
  291.  
  292.         pop  esi        ;POP ESI
  293.         pop  edi
  294.         pop  ecx
  295.         jmp  loop_        ;search next byte
  296.  
  297. patch:                ;start of the patcher
  298.         pop  esi        ;POP registers
  299.         pop  edi
  300.         pop  ecx
  301.         dec  edi        ;EDI-1
  302.         inc  ecx        ;ECX+1
  303.         mov  eax,fsize
  304.         sub  eax,ecx        ;compute Offset
  305.         push 0            ;offset from the beginning of the file
  306.         push 0            ;is 0, if file < 4,3GB
  307.         push eax        ;offset
  308.         push fhandle        ;filehandle
  309.         call SetFilePointer    ;set FilePointer
  310.  
  311.         push 0            ;normally 0
  312.         push offset bwrite    ;how many bytes where written?
  313.         push len        ;length of the bytes to write
  314.         push offset new_val    ;offset to new values
  315.         push fhandle        ;filehandle
  316.         Call WriteFile        ;write block to file
  317.  
  318.         push mb_ok 
  319.         push offset readycap    
  320.         push offset readytxt    
  321.     push hwnd
  322.         call MessageBoxA        ;OK, patch is done!
  323.  
  324.         jmp  end_kill_all    ;END! Cleanup!
  325.  
  326. not_found:
  327.  
  328.         push mb_ok              
  329.         push offset err_cap     
  330.         push offset byterr      
  331.         push hWnd               
  332.         call MessageBoxA        ;the bytes where not in the file
  333.  
  334. end_kill_all:
  335.  
  336.     push memptr        ;pointer to Memoryarea
  337.     call GlobalFree        ;enable (free) memory
  338.  
  339. end_kill_handle:
  340.  
  341.     push fhandle        ;PUSH filehandle
  342.     call CloseHandle    ;CloseHandle
  343.  
  344.  
  345. end_:
  346.  
  347.         CALL    ExitProcess     ;Quit program
  348. End Main                        ;end of code, JUMP-spot (main)
  349.  
  350. ;-----------------------==END OF SOURCE==----------------------------
  351.  
  352. ;-------------------------------START---------------------------make.bat
  353.  
  354. tasm32 /mx /m3 /z /q tut
  355. tlink32 -x /Tpe /aa /c tut,tut,, import32.lib
  356.  
  357. ;--------------------------------END----------------------------make.bat
  358.  
  359.             
  360.               --==A LITTLE NOTICE==--
  361.  
  362.     Until now I didn't see a reason to use include-files
  363.     And well, the INC-files coming with TASM are not very
  364.     complete, BUT if there is anybody out there possessing
  365.     complete *.incs then don't hesitate to send'em to me!
  366.  
  367.                 --==END==--
  368.  
  369. OK, I think this time we did something really useful, not just a MessageBox
  370. like in my first essay, but a real every-day-tool of a cracker.
  371. The source can be freely used naturally and maybe there are some things you
  372. can optimize, especially concerning the search-routine (Hi Fungus ;)), but
  373. I think for learning-purpose it is OK.
  374. For a little challenge: 
  375.  
  376. --> You could search for the first 4 bytes from the start
  377.  
  378.  
  379. OK, I hope that my mailbox (masta_t@USA.NET) will explode soon 
  380. (CRITICS ARE WELCOME) and I will see ya all next time ... =)  
  381. By the way I am trying to establish an IRC-channel about these facts ...
  382.  
  383. --> #win32asm
  384.  
  385. I just hope there are enough people interested in this stuff and also in
  386. giving there knowledge to others.
  387.  
  388.                       --==GREETINX==--
  389.  
  390.     VucoeT (Translator and Designer(:])), scut (Idea is from your 
  391.     DSP), |caligo| (bad news about you :(), fravia+ (best on the 
  392.     web), +Aescalapius (nice Bytepatcher) not4you (we Ossis must 
  393.     stick together ;)), fungus (something to optimze), Quest, 
  394.     Silvio, TheDoctor, everyone on #LAC and #cracking4newbies 
  395.     and to every cracker around the world.
  396.  
  397.  
  398.  
  399.                       --==WISE WORDS==--
  400.   -------====================--          --====================--------
  401. ------======everybody was a lamer, before they become ELITE======-------
  402.   -------====================--          --====================--------
  403.                           -----==========-----
  404.                    -
  405.