Ik dacht dat je C niet kon decompilen, maar ACM zei in mijn vorige post dat dat wel kon. Is er überhaubt nog wel iets wat NIET te decompilen is?
Het hangt er voornamelijk vanaf waarnaar je wilt decompileren en in hoeverre het op het origineel moet lijken
.
Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment
Stel iemand heeft een superformule bedacht. Hij denkt dat die, omdat die gecompileerd is, ook veilig is. Zit hij goed of niet?
Het kan, als je assembler kan lezen.Op zondag 30 juni 2002 17:35 schreef gang-ster het volgende:
Ik dacht dat je C niet kon decompilen, maar ACM zei in mijn vorige post dat dat wel kon. Is er überhaubt nog wel iets wat NIET te decompilen is?
Je kunt het zelfs weer naar C terug vertalen, als je het leuk vind om 1 joekel van een main te hebben met onbegrijpelijke variabele namen.
Verwijderd
Alles is te decompileren.. je hebt namelijk al de beschikking over de assembly code en deze kan worden omgezet naar c or whatever.. (hoe moeilijk het soms ook is)
Verwijderd
Nee, niet voor iemand met veel geduld die assembly kan lezen. Maar dat is ook logisch. Om een programma uit te kunnen voeren moet het te begrijpen zijn, een computer kan niks meer dan een mens, dus kan een mens de gecompileerde versie ook begrijpen als hij daar moeite voor doet.Op zondag 30 juni 2002 17:46 schreef gang-ster het volgende:
Stel iemand heeft een superformule bedacht. Hij denkt dat die, omdat die gecompileerd is, ook veilig is. Zit hij goed of niet?
>Je kunt het zelfs weer naar C terug vertalen, als je het
>leuk vind om 1 joekel van een main te hebben met
>onbegrijpelijke variabele namen.
Hoezo 1 main? Functies zijn makkelijk te herleiden vanuit de binaries, systeemcalls zeker, en als er nog verdwaalde debug-info in de binary zit, dan zelfs de originele functienamen en variabelen.
Maar goed, een functie genaamd "int TelOp(int getal1, int getal2)" is nog altijd duidelijker als int F1(int i14, int i15)", dus makkelijk zal het niet worden om expliciet elke functie terug te herleiden naar zijn originele functie.
>leuk vind om 1 joekel van een main te hebben met
>onbegrijpelijke variabele namen.
Hoezo 1 main? Functies zijn makkelijk te herleiden vanuit de binaries, systeemcalls zeker, en als er nog verdwaalde debug-info in de binary zit, dan zelfs de originele functienamen en variabelen.
Maar goed, een functie genaamd "int TelOp(int getal1, int getal2)" is nog altijd duidelijker als int F1(int i14, int i15)", dus makkelijk zal het niet worden om expliciet elke functie terug te herleiden naar zijn originele functie.
Yo dawg, I heard you like posts so I posted below your post so you can post again.
Het is niet gezegd dat je, gegeven een stukje assembly code, deze kunt omzetten naar C code (wanneer die niet met een C compiler gegenereert is, bijvoorbeeld) en daarbij zul je doorgaans niet zeker kunnen weten dat de door jou gevonden C code hetzelfde is als het origineel (identifiers helemaal buiten beschouwing gelaten) of dat de gevonden C compiler weer compileert tot dezelfde binary.Op zondag 30 juni 2002 18:39 schreef TimD het volgende:
Alles is te decompileren.. je hebt namelijk al de beschikking over de assembly code en deze kan worden omgezet naar c or whatever.. (hoe moeilijk het soms ook is)
De globale werking van een programma zal in het algemeen echter wel te herleiden zijn. Een C decompiler die in staat is om C code te produceren, die opnieuw gecompileerd tot een applicatie leidt die hetzelfde doet als de originele applicatie, moet ik nog tegenkomen. Lijkt me ook niet zo nuttig, trouwens. Programma's waarvan de broncode niet bekend is, mogen in de regel toch niet gedecompiled worden.
Die redenering klopt niet. Je zet het om naar een code die veel meer fine-grained is, en er gaat informatie over de structuur van het programma verloren. Het is echt niet zo simpel om van willekeurige machinecode weer een kloppend C programma te bakken, als het uberhaupt al mogelijk is. Je zult namelijk een structuur moeten verzinnen die past bij de gegenereerde code.Op zondag 30 juni 2002 18:39 schreef TimD het volgende:
Alles is te decompileren.. je hebt namelijk al de beschikking over de assembly code en deze kan worden omgezet naar c or whatever.. (hoe moeilijk het soms ook is)
"Logica brengt je van A naar B, verbeelding brengt je overal." - Albert Einstein
Min of meer wat ik ook al zei. Je kunt alleen zeggen, dat ALS de assembly code door een C compiler gegenereert is, er (in theorie) ook weer (tenminste één) C programma bij te vinden is.Op zondag 30 juni 2002 21:13 schreef Exirion het volgende:
Die redenering klopt niet. Je zet het om naar een code die veel meer fine-grained is, en er gaat informatie over de structuur van het programma verloren. Het is echt niet zo simpel om van willekeurige machinecode weer een kloppend C programma te bakken, als het uberhaupt al mogelijk is. Je zult namelijk een structuur moeten verzinnen die past bij de gegenereerde code.
Om uit de verschillende mogelijkheden dé originele broncode te halen, is een praktisch onmogelijke taak.
Kun je een voorbeeld geven van een stuk asm die volgens jou niet naar C om te zetten is? Volgens mij kan alles namelijk wel omgezet worden (Turing-compleet bla bla), al zal de gegenereerde code er niet echt mooi uitzien en zal het waarschijnlijk minder efficient zijn.Op zondag 30 juni 2002 21:13 schreef Exirion het volgende:
Die redenering klopt niet. Je zet het om naar een code die veel meer fine-grained is, en er gaat informatie over de structuur van het programma verloren. Het is echt niet zo simpel om van willekeurige machinecode weer een kloppend C programma te bakken, als het uberhaupt al mogelijk is. Je zult namelijk een structuur moeten verzinnen die past bij de gegenereerde code.
Verwijderd
als toch iets te decompilen is dan kunnen er toch ook stukken van de windows source vaag ontrafeld worden of mis ik nu iets?
Het hangt er een beetje van af, of de code door een bestaande compiler gegenereerd zou kunnen worden. Als ik een paar registers omwissel (stackpointer en basepointer, bijvoorbeeld) blijft m'n code hetzelfde werken maar zou geen bestaande C compiler de code genereren.Op zondag 30 juni 2002 21:31 schreef marcusk het volgende:
Kun je een voorbeeld geven van een stuk asm die volgens jou niet naar C om te zetten is? Volgens mij kan alles namelijk wel omgezet worden (Turing-compleet bla bla), al zal de gegenereerde code er niet echt mooi uitzien en zal het waarschijnlijk minder efficient zijn.
Natuurlijk is er wel weer een C compiler te verzinnen die ook zulke 'vreemde' code genereert, maar zo kun je wel bezig blijven.
In principe heb je wel gelijk dat elk programma in een willekeurige Turing-complete taal te schrijven is, maar de resulterende uitvoering zal in het algemeen wel verschillen.
Dat kan en gebeurt ook (is bijvoorbeeld gedaan met de Windows 95 bootloader), maar dat is in principe illegaal. Het is sowieso voor een groot deel handwerk om de assembly code (want zoals ik al zei, ken ik geen C decompilers) naar een leesbaar formaat om te zetten. Voor zulke gigantische projecten als Windows is dat niet te doen.Op zondag 30 juni 2002 21:36 schreef Pieter het volgende:
als toch iets te decompilen is dan kunnen er toch ook stukken van de windows source vaag ontrafeld worden of mis ik nu iets?
Verwijderd
is het dan onmogelijk om een progje te schrijven dat die binary terug zet naar prog code, als een mens dat kan waarom een computer niet?Op zondag 30 juni 2002 21:40 schreef Soultaker het volgende:
[..]
Dat kan en gebeurd ook (is bijvoorbeeld gaan met de Windows 95 bootloader), maar dat is in principe illegaal. Het is sowieso voor een groot deel handwerk om de assembly code (want zoals ik al zei, ken ik geen C decompilers) naar een leesbaar formaat om te zetten. Voor zulke gigantische projecten als Windows is dat niet te doen.
Er zijn zoveel dingen waarin een mens beter is dan een computer. Programmeren is voor een deel een creatief proces en dat creatieve deel is niet te programmeren.Op zondag 30 juni 2002 21:41 schreef Pieter het volgende:
is het dan onmogelijk om een progje te schrijven dat die binary terug zet naar prog code, als een mens dat kan waarom een computer niet?
Als je een Duitse tekst leest, kan een vertaalprogramma de letterlijke vertaling van elk woord geven. Aan de hand van grammaticaregels, kan er misschien nog wel een enigszins kloppende Nederlandse tekst geconstrueerd worden (al vallen de resultaten op dit vlak tot nu toe nog erg tegen). Om een spannend Duits boek om te zetten in een spannend Nederlands boek, is echter een Nederlandse vertaler nodig, die de essentie van het boek kan bevatten, die niet in de letterlijke formulering vastgelegd is.
Een compiler kan op eenzelfde manier wel assembly code omzetten naar C statements die vergelijkbare assembly code op zouden leveren, maar kan niet uitzoeken hoe het ontwerp van de applicatie in elkaar zit.
Er is uiteraard wel een verschil tussen een programmeertaal en een normale taal, maar in principe heb je wel gelijk. Op internet staan verschillende C-decompilers die van simpele gecompileerde programma's toch wel iets 'bruikbaars' maken, maar dit zijn dan vaak vrij simpele en niet-complexe programma's.Op zondag 30 juni 2002 21:53 schreef Soultaker het volgende:
[..]
Voor meer informatie over decompilatie en dan vooral of het mogelijk is om te decompileren verwijs ik je toch naar verschillende artikelen op het internet.
Op een internet-site vond ik het volgende stukje:
En op http://citeseer.nj.nec.com/weide94reverse.html vind je een paper over dit onderwerp. (Klik rechtsboven op View or Download)Is decompilation possible?
Almost every week requests for decompilation programs are made in newsgroups (like comp.lang.c), and these are usually replied with: It is not possible! People even write papers on the subject.
Fully automated decompilation is not possible -- this problem is theoretically equivalent to the Halting Problem, an undecidable problem in Computer Science. What this means is that decompilation cannot be achieved for all possible programs that are ever written, and that the separation of data and code is hard to achieve. Further, even if a certain degree of success is achieved, the generated program lacks meaningful variable and function names as these are not normally stored in an executable file (except when stored for debugging purposes).
Some people believe it is only possible to recover the assembly sources, this in itself is not a trivial problem, again, due to its equivalence to the Halting Problem. However, in practice, there have been approaches to deal with disassembly and decompilation. The more successful ones make use of extra information (e.g. knowledge of the compiler used) or require human input at the hard parts of the disassembly process.
Aangezien dit document ook een verwijzing bevat naar een - overigens legale - decompiler bevat, maar links naar decompilers volgens de FAQ niet zijn toegestaan, vermeld ik de bron in dit geval niet, tenzij een moderator alsnog toestemming geeft. Het document is overigens gemakkelijk met Google te vinden.
Gaat dat artikel niet over een stuk code dat willekeurig is?Op zondag 30 juni 2002 23:20 schreef elnino het volgende:
[..]
Maar de output van een c compiler is niet willekeurig (de transformatie ligt vast). Dus het lijkt mij dat in c gegenereerde code weer decompileerbaar naar geldige code (met verlies van bepaalde gegevens natuurlijk) moet zijn (uitgaande dat het alleen c-code is, dus geen asm/whatever er tussendoor).
Of kan het zijn dat twee originelen dezelfde output geven? Want dan heb je natuurlijk wel een probleem... maar je decomplatie moet geldige code geven, dus dan maakt de vorm van de code niet uit natuurlijk.
putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]
Verwijderd
Infinitive>> Als je weet welke compiler er gebruikt is voor het maken van de binary, ben je al een heel eind opweg met decompilen. Maar het is niet zo dat verschillende compilers de zelfde source tot een identieke binary zullen vertalen...
Voor iedereen die denkt dat decompiling eenvoudig is, denk nu eens alleen over disassembly na. Hoe kun je zelfmodificerende code fatsoenlijk disassemblen? Kun je hier dus ooit een C-source uit genereren?
Voor iedereen die denkt dat decompiling eenvoudig is, denk nu eens alleen over disassembly na. Hoe kun je zelfmodificerende code fatsoenlijk disassemblen? Kun je hier dus ooit een C-source uit genereren?
Theoretisch gezien kan je het als encryptie zien. Dan zou je brute-force kunnen gaan decompileren.
Dat lost uiteraard niet het identifier probleem op...
De vraag is, waarom iets decompileren als je het in minder tijd zelf (opnieuwe, van scratch) kan schrijven ?
Dat lost uiteraard niet het identifier probleem op...
De vraag is, waarom iets decompileren als je het in minder tijd zelf (opnieuwe, van scratch) kan schrijven ?
Het probleem zit em niet zozeer in welke "c"-instructie welke "asm"-instructies genereerd. Dit is vrij makkelijk te achterhalen en daardoor kan er redelijk dezelfde code uit tevoorschijn komen. Het probleem onstaat met variabelen- en functiebenamingen die niet meer te achterhalen zijn. Daarvoor moet je de essentie achterhalen van die functie, en dat is iets wat een computer/decompiler gewoonweg niet kan omdat hij niet in die context kan kijken.Op maandag 01 juli 2002 12:50 schreef mietje het volgende:
Infinitive>> Als je weet welke compiler er gebruikt is voor het maken van de binary, ben je al een heel eind opweg met decompilen. Maar het is niet zo dat verschillende compilers de zelfde source tot een identieke binary zullen vertalen...
Yo dawg, I heard you like posts so I posted below your post so you can post again.
Beter: hashingOp maandag 01 juli 2002 12:56 schreef XTerm89D het volgende:
Theoretisch gezien kan je het als encryptie zien. Dan zou je brute-force kunnen gaan decompileren.
- Vanuit een willekeurige hashcode kan je niet terug naar het exacte origineel.
- Een willekeurige hashcode hoeft geen origineel te hebben (bij een goede hashfunctie eigenlijk wel), dus theoretisch is dehashing onmogelijk gegeven een willekeurige hashfunctie.
- door brute force alle mogelijke inputs af te gaan, kan een input gevonden worden waarmee de hashcode overeen komt (dit kan een tijd duren, maar dat is niet van belang).
Is naamgeving voor correct werkende code (dus dat na compilatie van de decompilatie weer code ontstaat die hetzelfde werkt) belangrijk?Het probleem zit em niet zozeer in welke "c"-instructie welke "asm"-instructies genereerd. Dit is vrij makkelijk te achterhalen en daardoor kan er redelijk dezelfde code uit tevoorschijn komen. Het probleem onstaat met variabelen- en functiebenamingen die niet meer te achterhalen zijn. Daarvoor moet je de essentie achterhalen van die functie, en dat is iets wat een computer/decompiler gewoonweg niet kan omdat hij niet in die context kan kijken.
Zal
unsigned int i = 3
unsigned int x = 2 * i
printf("x: %u", x);
Een ander resultaat op het scherm zetten dan:
unsigned int b = 3
unsigned int abc = b << 1
printf("x: %u", abc);
putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]
Verwijderd
de meeste C compilers optimaliseren de gegenereerde code onder meer door het uitrollen van loops.
een while loop bijvoorbeeld kan daardoor een set instucties worden die NIET in een loop staan.
dus decompilen naar ASM gaat makkelijk, maar naar C, daar komt vrijwel nooit een programma uit wat lijkt op het orgineel.
een while loop bijvoorbeeld kan daardoor een set instucties worden die NIET in een loop staan.
dus decompilen naar ASM gaat makkelijk, maar naar C, daar komt vrijwel nooit een programma uit wat lijkt op het orgineel.
>Is naamgeving voor correct werkende code (dus dat na
>compilatie van de decompilatie weer code ontstaat die
>hetzelfde werkt) belangrijk?
Het ging over het feit of je de originele source weer terug kunt decompilen. Code-technisch is dit niet zo'n probleem, maar wel de benamingen van de variabelen die gebruikt zijn. Daar ging het over.
>compilatie van de decompilatie weer code ontstaat die
>hetzelfde werkt) belangrijk?
Het ging over het feit of je de originele source weer terug kunt decompilen. Code-technisch is dit niet zo'n probleem, maar wel de benamingen van de variabelen die gebruikt zijn. Daar ging het over.
Yo dawg, I heard you like posts so I posted below your post so you can post again.
Maar zo zijn er zat dingen:Op maandag 01 juli 2002 13:19 schreef Darts_GoT het volgende:
de meeste C compilers optimaliseren de gegenereerde code onder meer door het uitrollen van loops.
een while loop bijvoorbeeld kan daardoor een set instucties worden die NIET in een loop staan.
dus decompilen naar ASM gaat makkelijk, maar naar C, daar komt vrijwel nooit een programma uit wat lijkt op het orgineel.
code:
1
| movsw $5, -10(%ebp) |
kan ook nooit omgezet worden naar:
code:
1
2
| #define A 3
i = A + 2; |
Yo dawg, I heard you like posts so I posted below your post so you can post again.
Verwijderd
Dat is het probleem dus wel. Ten eerste is dit afhankelijk van de producent van de compiler, want niet elke compiler produceert de zelfde asm uit de zelfde source, en ten tweede is het binnen een compiler ook nog eens afhankelijk van tig opties zoals optimizing en debugging level.Op maandag 01 juli 2002 12:58 schreef JayTaph het volgende:
Het probleem zit em niet zozeer in welke "c"-instructie welke "asm"-instructies genereerd. Dit is vrij makkelijk te achterhalen en daardoor kan er redelijk dezelfde code uit tevoorschijn komen.
Laat ik nu denken dat variabelenamen en functienamen volledig arbitrair zijn, op de functienaam "main" na.Het probleem onstaat met variabelen- en functiebenamingen die niet meer te achterhalen zijn. Daarvoor moet je de essentie achterhalen van die functie, en dat is iets wat een computer/decompiler gewoonweg niet kan omdat hij niet in die context kan kijken.
Zelfs disassemblen is niet altijd mogelijk, en dat schrijf ik een post terug al. Je kunt een stukje zelfmodificerende code niet fatsoenlijk disassemblen.Op maandag 01 juli 2002 13:19 schreef Darts_GoT het volgende:
dus decompilen naar ASM gaat makkelijk, maar naar C, daar komt vrijwel nooit een programma uit wat lijkt op het orgineel.
Hoe kun je gecodeerde code lezen? Jullie zeggen de hele tijd assembler code enz, maar als ik bijv. mouse.exe van mijn muis open in notepad, dan zie ik vage tekens en echt geen patronen of zo iets.
Met een zogenaamde disassembler. Die zet machinetaal om in Assembler (ASM).Op woensdag 03 juli 2002 21:11 schreef gang-ster het volgende:
Hoe kun je gecodeerde code lezen? Jullie zeggen de hele tijd assembler code enz, maar als ik bijv. mouse.exe van mijn muis open in notepad, dan zie ik vage tekens en echt geen patronen of zo iets.
Is het nou eigenlijk Assembly of Assembler? Deze twee termen worden altijd door elkaar gehaald, maar wat is de juiste term (of mag het allebei)?
Dan wil jij iets anders doen dan wat een decompiler precies doet: namelijk PRECIES teruggaan naar de originele sourcecode, en dat is iets wat je op je buik kunt schrijven.Op maandag 01 juli 2002 13:53 schreef mietje het volgende:
Dat is het probleem dus wel. Ten eerste is dit afhankelijk van de producent van de compiler, want niet elke compiler produceert de zelfde asm uit de zelfde source, en ten tweede is het binnen een compiler ook nog eens afhankelijk van tig opties zoals optimizing en debugging level.
Het kan "codetechnisch" niemand veel uitmaken of "add [ebp+6],1" nu omgezet wordt naar "i++" of "i = i + 1", en dat is een onderscheid die jij wel wil maken, maar wat gewoonweg niet kan. Daarvoor zijn er teveel compilers, en opties zoals je zelf al aangeeft.
Kun je ongeveer nagaan hoe ik me voelde toen ik in een wedstrijd "wie hackt het snelst de paswoorden uit elkaars brouwsels"Zelfs disassemblen is niet altijd mogelijk, en dat schrijf ik een post terug al. Je kunt een stukje zelfmodificerende code niet fatsoenlijk disassemblen.
Yo dawg, I heard you like posts so I posted below your post so you can post again.
Spannende cliffhanger, hoe luidt de tweede helft van de zin?Op woensdag 03 juli 2002 22:24 schreef JayTaph het volgende:
Kun je ongeveer nagaan hoe ik me voelde toen ik in een wedstrijd "wie hackt het snelst de paswoorden uit elkaars brouwsels"
Verwijderd
Het is nog veel erger dan dat. Het probleem begint pas bij structures en vooral bij unions. Zo'n struct definitie is niet terug te vinden in de machinetaal, en zal moeten worden herleid uit de manier waarop velden in een struct door de machinecode afgehandeld worden. Bij unions wordt het helemaal vaag, want daar is er niet eens een eenduidige manier van afhandeling.Op woensdag 03 juli 2002 22:24 schreef JayTaph het volgende:
Het kan "codetechnisch" niemand veel uitmaken of "add [ebp+6],1" nu omgezet wordt naar "i++" of "i = i + 1", en dat is een onderscheid die jij wel wil maken, maar wat gewoonweg niet kan.
Het is voor een decompiler onmogelijk om een construct als deze te herleiden:
code:
1
2
3
4
5
6
7
| union register_type {
short word;
struct {
char lo,
hi;
} byte;
}; |
Pagina: 1