{"id":576,"date":"2017-06-12T10:24:04","date_gmt":"2017-06-12T10:24:04","guid":{"rendered":"http:\/\/www.max-sperling.bplaced.net\/?p=576"},"modified":"2024-02-16T10:16:47","modified_gmt":"2024-02-16T10:16:47","slug":"software-cracking-example-2","status":"publish","type":"post","link":"http:\/\/www.max-sperling.bplaced.net\/?p=576","title":{"rendered":"Software Cracking (Example 2)"},"content":{"rendered":"<p>This time we have got a KeyGenMe, which means the task is to write a KeyGen and not just to patch it or find a serial.<\/p>\n<p><strong>0. Building<\/strong><br \/>\nThis step is just happening cause I have written the KeyGenMe by my own. The executable of the code was build with MinGW as an PE x86.<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n \r\nint main()\r\n{\r\n    char nameInp[128] = {&#039;&#92;&#48;&#039;};\r\n    fputs(&quot;Name:&quot;, stdout);\r\n    fgets(nameInp, sizeof(nameInp), stdin);\r\n    nameInp[strlen(nameInp)-1] = &#039;&#92;&#48;&#039;;\r\n\r\n    char serialInp[sizeof(int)];\r\n    fputs(&quot;Serial:&quot;, stdout);\r\n    fgets(serialInp, sizeof(serialInp), stdin);\r\n    serialInp[strlen(serialInp)-1] = &#039;&#92;&#48;&#039;;\r\n\r\n    unsigned int serial = 0;\r\n    for(unsigned int i=0; i&lt;strlen(nameInp); i++)\r\n    {\r\n        serial += nameInp[i];\r\n    }\r\n\r\n\tif(atoi(serialInp) != serial)\r\n    {\r\n        fputs(&quot;Access denied&quot;, stdout);\r\n        return 1;\r\n    }\r\n\r\n    fputs(&quot;Access granted&quot;, stdout);\r\n    return 0;\r\n}\r\n<\/pre>\n<p><strong>1. Disassembling<\/strong><br \/>\nThe following interesting part of the code is shown from OllyDbg after disassembling the PE x86 executable with it.<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\n00401620  MOV DWORD PTR SS:[ESP],a.00404044      ; ||||||ASCII &quot;Name:&quot;\r\n00401627  CALL &lt;JMP.&amp;msvcrt.fwrite&gt;              ; |||||\\fwrite\r\n0040162C  MOV EAX,DWORD PTR DS:[&lt;&amp;msvcrt._iob&gt;]  ; |||||\r\n00401631  MOV DWORD PTR SS:[ESP+8],EAX           ; |||||\r\n00401635  MOV DWORD PTR SS:[ESP+4],80            ; |||||\r\n0040163D  LEA EAX,DWORD PTR SS:[ESP+18]          ; |||||\r\n00401641  MOV DWORD PTR SS:[ESP],EAX             ; |||||\r\n00401644  CALL &lt;JMP.&amp;msvcrt.fgets&gt;               ; ||||\\fgets\r\n00401649  LEA EAX,DWORD PTR SS:[ESP+18]          ; ||||\r\n0040164D  MOV DWORD PTR SS:[ESP],EAX             ; ||||\r\n00401650  CALL &lt;JMP.&amp;msvcrt.strlen&gt;              ; |||\\strlen\r\n00401655  SUB EAX,1                              ; |||\r\n00401658  MOV BYTE PTR SS:[ESP+EAX+18],0         ; |||\r\n0040165D  MOV EAX,DWORD PTR DS:[&lt;&amp;msvcrt._iob&gt;]  ; |||\r\n00401662  ADD EAX,20                             ; |||\r\n00401665  MOV DWORD PTR SS:[ESP+C],EAX           ; |||\r\n00401669  MOV DWORD PTR SS:[ESP+8],7             ; |||\r\n00401671  MOV DWORD PTR SS:[ESP+4],1             ; |||\r\n00401679  MOV DWORD PTR SS:[ESP],a.0040404A      ; |||ASCII &quot;Serial:&quot;\r\n00401680  CALL &lt;JMP.&amp;msvcrt.fwrite&gt;              ; ||\\fwrite\r\n00401685  MOV EAX,DWORD PTR DS:[&lt;&amp;msvcrt._iob&gt;]  ; ||\r\n0040168A  MOV DWORD PTR SS:[ESP+8],EAX           ; ||\r\n0040168E  MOV DWORD PTR SS:[ESP+4],4             ; ||\r\n00401696  LEA EAX,DWORD PTR SS:[ESP+14]          ; ||\r\n0040169A  MOV DWORD PTR SS:[ESP],EAX             ; ||\r\n0040169D  CALL &lt;JMP.&amp;msvcrt.fgets&gt;               ; |\\fgets\r\n004016A2  LEA EAX,DWORD PTR SS:[ESP+14]          ; |\r\n004016A6  MOV DWORD PTR SS:[ESP],EAX             ; |\r\n004016A9  CALL &lt;JMP.&amp;msvcrt.strlen&gt;              ; \\strlen\r\n004016AE  SUB EAX,1\r\n004016B1  MOV BYTE PTR SS:[ESP+EAX+14],0\r\n004016B6  MOV DWORD PTR SS:[ESP+9C],0\r\n004016C1  MOV DWORD PTR SS:[ESP+98],0\r\n004016CC  \/LEA EAX,DWORD PTR SS:[ESP+18]         ; |\r\n004016D0  |MOV DWORD PTR SS:[ESP],EAX            ; |\r\n004016D3  |CALL &lt;JMP.&amp;msvcrt.strlen&gt;             ; \\strlen\r\n004016D8  |CMP DWORD PTR SS:[ESP+98],EAX\r\n004016DF  |JNB SHORT a.00401705\r\n004016E1  |LEA EDX,DWORD PTR SS:[ESP+18]\r\n004016E5  |MOV EAX,DWORD PTR SS:[ESP+98]\r\n004016EC  |ADD EAX,EDX\r\n004016EE  |MOVZX EAX,BYTE PTR DS:[EAX]\r\n004016F1  |MOVSX EAX,AL\r\n004016F4  |ADD DWORD PTR SS:[ESP+9C],EAX\r\n004016FB  |ADD DWORD PTR SS:[ESP+98],1\r\n00401703  \\JMP SHORT a.004016CC\r\n00401705  LEA EAX,DWORD PTR SS:[ESP+14]          ; ||\r\n00401709  MOV DWORD PTR SS:[ESP],EAX             ; ||\r\n0040170C  CALL &lt;JMP.&amp;msvcrt.atoi&gt;                ; |\\atoi\r\n00401711  CMP DWORD PTR SS:[ESP+9C],EAX          ; |\r\n00401718  SETNE AL                               ; |\r\n0040171B  TEST AL,AL                             ; |\r\n0040171D  JE SHORT a.0040174E                    ; |\r\n0040171F  MOV EAX,DWORD PTR DS:[&lt;&amp;msvcrt._iob&gt;]  ; |\r\n00401724  ADD EAX,20                             ; |\r\n00401727  MOV DWORD PTR SS:[ESP+C],EAX           ; |\r\n0040172B  MOV DWORD PTR SS:[ESP+8],0D            ; |\r\n00401733  MOV DWORD PTR SS:[ESP+4],1             ; |\r\n0040173B  MOV DWORD PTR SS:[ESP],a.00404052      ; |ASCII &quot;Access denied&quot;\r\n00401742  CALL &lt;JMP.&amp;msvcrt.fwrite&gt;              ; \\fwrite\r\n00401747  MOV EAX,1\r\n0040174C  JMP SHORT a.0040177B\r\n0040174E  MOV EAX,DWORD PTR DS:[&lt;&amp;msvcrt._iob&gt;]  ; |\r\n00401753  ADD EAX,20                             ; |\r\n00401756  MOV DWORD PTR SS:[ESP+C],EAX           ; |\r\n0040175A  MOV DWORD PTR SS:[ESP+8],0E            ; |\r\n00401762  MOV DWORD PTR SS:[ESP+4],1             ; |\r\n0040176A  MOV DWORD PTR SS:[ESP],a.00404060      ; |ASCII &quot;Access granted&quot;\r\n00401771  CALL &lt;JMP.&amp;msvcrt.fwrite&gt;              ; \\fwrite\r\n<\/pre>\n<p><strong>2. Interpreting<\/strong><br \/>\nAt the beginning it reads a name and a serial from stdin. Then it calculates a value in a loop. After that it converts the entered serial to int and compares it with the calculated value from the loop. If it is the same it granted you access else it denied you access.<\/p>\n<p>The following code shows the loop part.<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\n004016B6  MOV DWORD PTR SS:[ESP+9C],0     ; val = 0\r\n004016C1  MOV DWORD PTR SS:[ESP+98],0     ; idx = 0\r\n004016CC  \/LEA EAX,DWORD PTR SS:[ESP+18]  ; lbl &#039;START&#039;\r\n004016D0  |MOV DWORD PTR SS:[ESP],EAX     ; get &amp;name[0]\r\n004016D3  |CALL &lt;JMP.&amp;msvcrt.strlen&gt;      ; len = strlen(name)\r\n004016D8  |CMP DWORD PTR SS:[ESP+98],EAX  ; cmp idx with len\r\n004016DF  |JNB SHORT a.00401705           ; if &gt;= then jmp to &#039;EXIT&#039;\r\n004016E1  |LEA EDX,DWORD PTR SS:[ESP+18]  ; get &amp;name[0]\r\n004016E5  |MOV EAX,DWORD PTR SS:[ESP+98]  ; get i\r\n004016EC  |ADD EAX,EDX                    ; &amp;name[i] = &amp;name[0] + i\r\n004016EE  |MOVZX EAX,BYTE PTR DS:[EAX]    ; get (high char) name[i]\r\n004016F1  |MOVSX EAX,AL                   ; get (low char) name[i]\r\n004016F4  |ADD DWORD PTR SS:[ESP+9C],EAX  ; val += name[i]\r\n004016FB  |ADD DWORD PTR SS:[ESP+98],1    ; i++\r\n00401703  \\JMP SHORT a.004016CC           ; jmp to &#039;START&#039;\r\n00401705  LEA EAX,DWORD PTR SS:[ESP+14]   ; lbl &#039;EXIT&#039;\r\n<\/pre>\n<p>==> The calculated value is the sum of all ASCII codes of the chars in the name.<\/p>\n<p><strong>3. Generating<\/strong><br \/>\nAfter we understood the algorithm of the serial calculation based on the entered name we can now program the KeyGen. In this case I have written it in C.<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\nint main()\r\n{\r\n    char nameInp[128] = {&#039;&#92;&#48;&#039;};\r\n    fputs(&quot;Name:&quot;, stdout);\r\n    fgets(nameInp, sizeof(nameInp), stdin);\r\n    nameInp[strlen(nameInp)-1] = &#039;&#92;&#48;&#039;;\r\n\r\n    unsigned int serial = 0;\r\n    for(unsigned int i=0; i&lt;strlen(nameInp); i++)\r\n    {\r\n        serial += nameInp[i];\r\n    }\r\n\r\n    printf(&quot;Serial: %i&quot;, serial);\r\n    return 0;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This time we have got a KeyGenMe, which means the task is to write a KeyGen and not just to<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false},"categories":[39],"tags":[],"_links":{"self":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/576"}],"collection":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=576"}],"version-history":[{"count":1,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/576\/revisions"}],"predecessor-version":[{"id":16716,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/576\/revisions\/16716"}],"wp:attachment":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=576"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}