{"id":27154993,"url":"https://github.com/maximilianfeldthusen/x86backtoc","last_synced_at":"2025-08-04T01:34:58.589Z","repository":{"id":190355622,"uuid":"682450690","full_name":"maximilianfeldthusen/x86BackToC","owner":"maximilianfeldthusen","description":"Turn a x86 binary back into C source code","archived":false,"fork":false,"pushed_at":"2025-07-03T04:29:56.000Z","size":30,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"TFD","last_synced_at":"2025-07-03T05:24:54.672Z","etag":null,"topics":["assembly","c","reverse-engineering"],"latest_commit_sha":null,"homepage":"","language":"Assembly","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maximilianfeldthusen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-08-24T07:39:18.000Z","updated_at":"2025-07-03T04:32:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"6f80611d-b34c-4b72-99c9-3438f76d40cc","html_url":"https://github.com/maximilianfeldthusen/x86BackToC","commit_stats":null,"previous_names":["torbenfeldthusen/x86backtoc","maximilianfeldthusen/x86backtoc"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/maximilianfeldthusen/x86BackToC","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximilianfeldthusen%2Fx86BackToC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximilianfeldthusen%2Fx86BackToC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximilianfeldthusen%2Fx86BackToC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximilianfeldthusen%2Fx86BackToC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maximilianfeldthusen","download_url":"https://codeload.github.com/maximilianfeldthusen/x86BackToC/tar.gz/refs/heads/TFD","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maximilianfeldthusen%2Fx86BackToC/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268636899,"owners_count":24282200,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-03T02:00:12.545Z","response_time":2577,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assembly","c","reverse-engineering"],"created_at":"2025-04-08T18:56:43.466Z","updated_at":"2025-08-04T01:34:58.575Z","avatar_url":"https://github.com/maximilianfeldthusen.png","language":"Assembly","funding_links":[],"categories":[],"sub_categories":[],"readme":"## x86BackToC\n\n### Turn a x86 binary back into C source code\n\n\n![C](https://img.shields.io/badge/c-%2300599C.svg?style=for-the-badge\u0026logo=c\u0026logoColor=white)\n    \n ![AssemblyScript](https://img.shields.io/badge/assembly%20script-%23000000.svg?style=for-the-badge\u0026logo=assemblyscript\u0026logoColor=white)\n\n---\n\ntitle: \"Turn a x86 binary back into C code\"\nlayout: post\ndate: 2025-05-25 22:44\nheaderImage: false\ntag:\n- assembly\n- c\n- reverse engineering\nstar: true\ncategory: blog\nauthor: maximilian feldthusen\ndescription: Reverse Engineering\n---\n \n\n * Objective: turn a x86 binary executable back into C source code. \n * Understand how the compiler turns C into assembly code. \n * Low-level OS structures and executable file format.\n \nArithmetic Instructions\n```c\nmov eax,2 ; eax = 2 \nmov ebx,3 ; ebx = 3\nadd eax,ebx ; eax = eax + ebx \nsub ebx, 2 ; ebx = ebx - 2\n```\nAccessing Memory\n```c\nmox eax, [1234] ; eax = *(int*)1234 \nmov ebx, 1234 ; ebx = 1234 \nmov eax, [ebx] ; eax = *ebx \nmov [ebx], eax ; *ebx = eax \n\n```\nConditional Branches\n\n```c\ncmp eax, 2 ; compare eax with 2 \nje label1 ; if(eax==2) goto label1\n ja label2 ; if(eax\u003e2) goto label2\njb label3 ; if(eax\u003c2) goto label3 \njbe label4 ; if(eax\u003c=2) goto label4\n jne label5 ; if(eax!=2) goto label5\n jmp label6 ; unconditional goto label6\n\n```\nFunction calls\n\nFirst calling a function:\ncall func ; store return address on the stack and jump to func \nThe first operations is to save the return pointer:\n```c\npop esi ; save esi \nRight before leaving the function:\npop esi ; restore esi\nret ; read return address from the stack and jump to it \n```\nModern Compiler Architecture\n\nC code --\u003e Parsing --\u003e Intermediate representation --\u003e optimization --\u003e \nLow-level intermediate representation --\u003e register allocation --\u003e x86 assembly\n\n\nHigh-level Optimizations\n\nInlining\n\nFor example, the function c:\n```c\nint foo(int a, int b){\n     return a+b }\n c = foo(a, b+1) \n```\n\ntranslates to \n```c\nc = a+b+1\n```\n \nLoop unrolling\n\nThe loop:\n```c\nfor(i=0; i\u003c2; i++){\n      a[i]=0;\n }\n \n```\n\nbecomes\n\n```c\n   a[0]=0; \n   a[1]=0; \n\n```\nLoop-invariant code motion\n```c\nThe loop:\nfor (i = 0; i \u003c 2; i++) {\n a[i] = p + q; \n} \n\n```\nbecomes:\n\n```c\n\ntemp = p + q;\nfor (i = 0; i \u003c 2; i++) {\n    a[i] = temp;\n}\n \n```\nCommon subexpression elimination\n\nThe variable attributions:\n\n * Objective: turn a x86 binary executable back into C source code. \n * Understand how the compiler turns C into assembly code. \n * Low-level OS structures and executable file format.\n \nArithmetic Instructions\n```c\nmov eax,2 ; eax = 2 \nmov ebx,3 ; ebx = 3\nadd eax,ebx ; eax = eax + ebx \nsub ebx, 2 ; ebx = ebx - 2\n```\nAccessing Memory\n```c\nmox eax, [1234] ; eax = *(int*)1234 \nmov ebx, 1234 ; ebx = 1234 \nmov eax, [ebx] ; eax = *ebx \nmov [ebx], eax ; *ebx = eax \n\n```\nConditional Branches\n\n```c\ncmp eax, 2 ; compare eax with 2 \nje label1 ; if(eax==2) goto label1\n ja label2 ; if(eax\u003e2) goto label2\njb label3 ; if(eax\u003c2) goto label3 \njbe label4 ; if(eax\u003c=2) goto label4\n jne label5 ; if(eax!=2) goto label5\n jmp label6 ; unconditional goto label6\n\n```\nFunction calls\n\nFirst calling a function:\ncall func ; store return address on the stack and jump to func \nThe first operations is to save the return pointer:\n```c\npop esi ; save esi \nRight before leaving the function:\npop esi ; restore esi\nret ; read return address from the stack and jump to it \n```\nModern Compiler Architecture\n\nC code --\u003e Parsing --\u003e Intermediate representation --\u003e optimization --\u003e \nLow-level intermediate representation --\u003e register allocation --\u003e x86 assembly\n\n\nHigh-level Optimizations\n\nInlining\n\nFor example, the function c:\n```c\nint foo(int a, int b){\n     return a+b }\n c = foo(a, b+1) \n```\n\ntranslates to \n```c\nc = a+b+1\n```\n \nLoop unrolling\n\nThe loop:\n```c\nfor(i=0; i\u003c2; i++){\n      a[i]=0;\n } \n```\n\nbecomes\n\n```c\n   a[0]=0; \n   a[1]=0; \n\n```\nLoop-invariant code motion\n```c\nThe loop:\nfor (i = 0; i \u003c 2; i++) {\n a[i] = p + q; \n} \n```\nbecomes:\n```c\ntemp = p + q;\nfor (i = 0; i \u003c 2; i++) {\n    a[i] = temp;\n}\n \n```\nCommon subexpression elimination\n\nThe variable attributions:\n```c\na = b + (z + 1)\np = q + (z + 1)\n```\nbecomes\n```c\ntemp = z + 1\na = b + z\np = q + z\n\n```\nConstant folding and propagation\n\nThe assignments:\n```c\na = 3 + 5\nb = a + 1\nfunc(b)\n```\nBecomes:\n```c\nfunc(9)\n\n```\nDead code elimination\n\nDelete unnecessary code:\n```c\na = 1\nif (a \u003c 0) {\nprintf(“ERROR!”)\n}\n```\nto\n```c\na = 1\n\n```\nLow-Level Optimizations\n\nStrength reduction\n\nCodes such as:\n```c\ny = x * 2\ny = x * 15\n```\nBecomes:\n```c\ny = x + x\ny = (x \u003c\u003c 4) - x\n\n```\nCode block reordering\n\nCodes such as :\n```c\nif (a \u003c 10) goto l1\nprintf(“ERROR”)\ngoto label2\nl1:\n    printf(“OK”)\nl2:\n    return;\n```\nBecomes:\n```c\nif (a \u003e 10) goto l1\nprintf(“OK”)\nl2:\nreturn\nl1:\nprintf(“ERROR”)\ngoto l2\n\n```\nRegister allocation\n\n * Memory access is slower than registers. \n * Try to fit as many as local variables as possible in registers. \n * The mapping of local variables to stack location and registers is not constant.\n \n \n\nInstruction scheduling\n\nAssembly code like:\n```c\nmov eax, [esi]\nadd eax, 1\nmov ebx, [edi]\nadd ebx, 1\n```\nBecomes:\n```c\nmov eax, [esi]\nmov ebx, [edi]\nadd eax, 1\nadd ebx, 1\n\na = b + (z + 1)\np = q + (z + 1)\n```\nbecomes\n```c\ntemp = z + 1\na = b + z\np = q + z\n\n```\nConstant folding and propagation\n\nThe assignments:\n```c\na = 3 + 5\nb = a + 1\nfunc(b)\n```\nBecomes:\n```c\nfunc(9)\n\n```\nDead code elimination\n\nDelete unnecessary code:\n```c\na = 1\nif (a \u003c 0) {\nprintf(“ERROR!”)\n}\n```\nto\n```c\na = 1\n\n```\nLow-Level Optimizations\n\nStrength reduction\n\nCodes such as:\n```c\ny = x * 2\ny = x * 15\n```\nBecomes:\n```c\ny = x + x\ny = (x \u003c\u003c 4) - x\n\n```\nCode block reordering\n\nCodes such as :\n```c\nif (a \u003c 10) goto l1\nprintf(“ERROR”)\ngoto label2\nl1:\n    printf(“OK”)\nl2:\n    return;\n```\nBecomes:\n```c\nif (a \u003e 10) goto l1\nprintf(“OK”)\nl2:\nreturn\nl1:\nprintf(“ERROR”)\ngoto l2\n\n```\nRegister allocation\n\n * Memory access is slower than registers. \n * Try to fit as many as local variables as possible in registers. \n * The mapping of local variables to stack location and registers is not constant.\n \n\n * Objective: turn a x86 binary executable back into C source code. \n * Understand how the compiler turns C into assembly code. \n * Low-level OS structures and executable file format.\n \nArithmetic Instructions\n```c\nmov eax,2 ; eax = 2 \nmov ebx,3 ; ebx = 3\nadd eax,ebx ; eax = eax + ebx \nsub ebx, 2 ; ebx = ebx - 2\n```\nAccessing Memory\n```c\nmox eax, [1234] ; eax = *(int*)1234 \nmov ebx, 1234 ; ebx = 1234 \nmov eax, [ebx] ; eax = *ebx \nmov [ebx], eax ; *ebx = eax \n\n```\nConditional Branches\n\n```c\ncmp eax, 2 ; compare eax with 2 \nje label1 ; if(eax==2) goto label1\n ja label2 ; if(eax\u003e2) goto label2\njb label3 ; if(eax\u003c2) goto label3 \njbe label4 ; if(eax\u003c=2) goto label4\n jne label5 ; if(eax!=2) goto label5\n jmp label6 ; unconditional goto label6\n\n```\nFunction calls\n\nFirst calling a function:\ncall func ; store return address on the stack and jump to func \nThe first operations is to save the return pointer:\n```c\npop esi ; save esi \nRight before leaving the function:\npop esi ; restore esi\nret ; read return address from the stack and jump to it \n```\nModern Compiler Architecture\n\nC code --\u003e Parsing --\u003e Intermediate representation --\u003e optimization --\u003e \nLow-level intermediate representation --\u003e register allocation --\u003e x86 assembly\n\n\nHigh-level Optimizations\n\nInlining\n\nFor example, the function c:\n```c\nint foo(int a, int b){\n     return a+b }\n c = foo(a, b+1) \n\n```\n\ntranslates to \n```c\nc = a+b+1\n```\n \nLoop unrolling\n\nThe loop:\n```c\nfor(i=0; i\u003c2; i++){\n      a[i]=0;\n } \n```\n```c\nbecomes\n   a[0]=0; \n   a[1]=0; \n\n```\nLoop-invariant code motion\n\nThe loop:\n```c\nfor (i = 0; i \u003c 2; i++) {\n a[i] = p + q; \n} \n```\nbecomes:\n```c\ntemp = p + q;\nfor (i = 0; i \u003c 2; i++) {\n    a[i] = temp;\n}\n \n```\nCommon subexpression elimination\n\nThe variable attributions:\n\n * Objective: turn a x86 binary executable back into C source code. \n * Understand how the compiler turns C into assembly code. \n * Low-level OS structures and executable file format.\n \nArithmetic Instructions\n```c\nmov eax,2 ; eax = 2 \nmov ebx,3 ; ebx = 3\nadd eax,ebx ; eax = eax + ebx \nsub ebx, 2 ; ebx = ebx - 2\n```\nAccessing Memory\n```c\nmox eax, [1234] ; eax = *(int*)1234 \nmov ebx, 1234 ; ebx = 1234 \nmov eax, [ebx] ; eax = *ebx \nmov [ebx], eax ; *ebx = eax \n\n```\nConditional Branches\n\n```c\ncmp eax, 2 ; compare eax with 2 \nje label1 ; if(eax==2) goto label1\n ja label2 ; if(eax\u003e2) goto label2\njb label3 ; if(eax\u003c2) goto label3 \njbe label4 ; if(eax\u003c=2) goto label4\n jne label5 ; if(eax!=2) goto label5\n jmp label6 ; unconditional goto label6\n\n```\nFunction calls\n\nFirst calling a function:\ncall func ; store return address on the stack and jump to func \nThe first operations is to save the return pointer:\n```c\npop esi ; save esi \nRight before leaving the function:\npop esi ; restore esi\nret ; read return address from the stack and jump to it \n```\nModern Compiler Architecture\n\nC code --\u003e Parsing --\u003e Intermediate representation --\u003e optimization --\u003e \nLow-level intermediate representation --\u003e register allocation --\u003e x86 assembly\n\n\nHigh-level Optimizations\n\nInlining\n\nFor example, the function c:\n```c\nint foo(int a, int b){\n     return a+b }\n c = foo(a, b+1) \n```\n\ntranslates to \n```c\nc = a+b+1\n```\n \nLoop unrolling\n\nThe loop:\n```c\nfor(i=0; i\u003c2; i++){\n      a[i]=0;\n } \n```\n\nbecomes\n\n```c\n   a[0]=0; \n   a[1]=0; \n\n```\nLoop-invariant code motion\n```c\nThe loop:\nfor (i = 0; i \u003c 2; i++) {\n a[i] = p + q; \n} \n```\nbecomes:\n```c\ntemp = p + q;\nfor (i = 0; i \u003c 2; i++) {\n    a[i] = temp;\n}\n \n```\nCommon subexpression elimination\n\n\n\nThe variable attributions:\n```c\na = b + (z + 1)\np = q + (z + 1)\n```\nbecomes\n```c\ntemp = z + 1\na = b + z\np = q + z\n\n```\nConstant folding and propagation\n\nThe assignments:\n```c\na = 3 + 5\nb = a + 1\nfunc(b)\n```\nBecomes:\n```c\nfunc(9)\n\n```\nDead code elimination\n\nDelete unnecessary code:\n```c\na = 1\nif (a \u003c 0) {\nprintf(“ERROR!”)\n}\n```\nto\n```c\na = 1\n\n```\nLow-Level Optimizations\n\nStrength reduction\n\nCodes such as:\n```c\ny = x * 2\ny = x * 15\n```\nBecomes:\n```c\ny = x + x\ny = (x \u003c\u003c 4) - x\n\n```\nCode block reordering\n\nCodes such as :\n```c\nif (a \u003c 10) goto l1\nprintf(“ERROR”)\ngoto label2\nl1:\n    printf(“OK”)\nl2:\n    return;\n```\nBecomes:\n```c\nif (a \u003e 10) goto l1\nprintf(“OK”)\nl2:\nreturn\nl1:\nprintf(“ERROR”)\ngoto l2\n\n```\nRegister allocation\n\n * Memory access is slower than registers. \n * Try to fit as many as local variables as possible in registers. \n * The mapping of local variables to stack location and registers is not constant.\n \n \n\nInstruction scheduling\n\nAssembly code like:\n```c\nmov eax, [esi]\nadd eax, 1\nmov ebx, [edi]\nadd ebx, 1\n```\nBecomes:\n```c\nmov eax, [esi]\nmov ebx, [edi]\nadd eax, 1\nadd ebx, 1\n\na = b + (z + 1)\np = q + (z + 1)\n```\nbecomes\n```c\ntemp = z + 1\na = b + z\np = q + z\n\n```\nConstant folding and propagation\n\nThe assignments:\n```c\na = 3 + 5\nb = a + 1\nfunc(b)\n```\nBecomes:\n```c\nfunc(9)\n\n```\nDead code elimination\n\nDelete unnecessary code:\n```c\na = 1\nif (a \u003c 0) {\nprintf(“ERROR!”)\n}\n```\nto\n```c\na = 1\n\n```\nLow-Level Optimizations\n\nStrength reduction\n\nCodes such as:\n```c\ny = x * 2\ny = x * 15\n```\nBecomes:\n```c\ny = x + x\ny = (x \u003c\u003c 4) - x\n\n```\nCode block reordering\n\nCodes such as :\n```c\nif (a \u003c 10) goto l1\nprintf(“ERROR”)\ngoto label2\nl1:\n    printf(“OK”)\nl2:\n    return;\n```\nBecomes:\n```c\nif (a \u003e 10) goto l1\nprintf(“OK”)\nl2:\nreturn\nl1:\nprintf(“ERROR”)\ngoto l2\n\n```\nRegister allocation\n\n * Memory access is slower than registers. \n * Try to fit as many as local variables as possible in registers. \n * The mapping of local variables to stack location and registers is not constant.\n \n \n\nInstruction scheduling\n\nAssembly code like:\n```c\nmov eax, [esi]\nadd eax, 1\nmov ebx, [edi]\nadd ebx, 1\n```\nBecomes:\n```c\nmov eax, [esi]\nmov ebx, [edi]\nadd eax, 1\nadd ebx, 1\n\n```\nInstruction scheduling\n\nAssembly code like:\n```c\nmov eax, [esi]\nadd eax, 1\nmov ebx, [edi]\nadd ebx, 1\n```\nBecomes:\n```c\nmov eax, [esi]\nmov ebx, [edi]\nadd eax, 1\nadd ebx, 1\n\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaximilianfeldthusen%2Fx86backtoc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaximilianfeldthusen%2Fx86backtoc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaximilianfeldthusen%2Fx86backtoc/lists"}