Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Reverse engineeren, waarom moeilijk?

Pagina: 1
Acties:

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
Zojuist las ik nieuws: VU krijgt miljoenensubsidie voor reverse engineering-project en toen vroeg ik me af: waarom is reverse engineering eigenlijk moeilijk?

Ik had altijd begrepen dat een compiler de gewone code vertaalt naar machinetaal. Als dat zo is, waarom is dan het terugvertalen zo ingewikkeld? (vgl. Engels-->Nederlands-->Engels).

Zelf programmeer ik alleen maar simpele web-gerelateerde talen, dus hopelijk gebruiken jullie niet teveel moeilijke woorden :-)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Omdat er tijdens de compilatie informatie verloren gaat en er ook dingen worden toegevoegd door de compiler die niet direct in de originele broncode stonden, maar impliciet nodig zijn, zoals destructor aanroepen bijvoorbeeld. Verder wordt de code door moderne compilers helemaal door elkaar heen geregen voor performance, dus je moet al die apparte strands er weer uithalen en leesbaar maken.

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 19:09

Reptile209

- gers -

Om je vergelijking te gebruiken: het is al niet triviaal om EN > NL > EN te vertalen. Er zijn meerdere zinsconstructies die ongeveer hetzelfde kunnen betekenen, maar verschillen in de nuances (bijvoorbeeld beleefdheidsvormen, nadruk, formeel, informeel, lange zinnen, korte zinnen, enz.)
Met programmacode is dat niet veel anders. De compiler zet de code om in hapklare brokken voor de CPU. Het terugvertalen van die brokken naar (makkelijk) leesbare code is niet zo simpel. Je wil niet een stuk van een ingewikkelde berekening stapje voor stapje terugvinden in je code, dat wordt onleesbaar.
Laatste lastige punt: bij het compileren gaat meestal de extra informatie als namen van functies en variabelen verloren. Je krijgt dan dus functie a() met variabelen b, c en d terug (nog gecompliceerder, maar je snapt het punt wel), terwijl het oorspronkelijk AddUser(Name, Function, Salary) was. Welke leest beter?

Zo scherp als een voetbal!


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Rekcor schreef op woensdag 11 augustus 2010 @ 10:58:
Ik had altijd begrepen dat een compiler de gewone code vertaalt naar machinetaal. Als dat zo is, waarom is dan het terugvertalen zo ingewikkeld? (vgl. Engels-->Nederlands-->Engels).
Maar ook het vertalen van Engels->Nederlands->Engels is niet zo triviaal als het lijkt. Je krijgt waarschijnlijk niet snel exact dezelfde output als input. Bij moeilijkere teksten krijg je er misschien zelfs een compleet andere betekenis uit ( Kijk maar naar de discussie die er bestaat over vertalingen van de bijbel )

Verder is de originele structuur ook niet meer goed te achterhalen. Als je bijvoorbeeld een methode gemaakt hebt, staat het de compiler vrij (Met wat restricties) om dat stuk code gewoon te kopieren naar de aanroepende methode. En sowieso zijn de labels (methode/variabele-namen) niet nodig in de gecompileerde versie, dus die zijn ook niet meer te achterhalen.

Zo gaat er nog veel meer informatie verloren bij het compilatie proces

[ Voor 3% gewijzigd door Woy op 11-08-2010 11:19 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • TheLunatic
  • Registratie: April 2001
  • Laatst online: 16-08 21:48

TheLunatic

Ouwe boxen.

En volgens mij ook omdat wat voor een programmeur een enkele functie is met wat simpele argumenten, uiteindelijk in 'machinetaal' wordt omgezet naar honderden kleine statements.

Mother, will they like this song?


  • SinergyX
  • Registratie: November 2001
  • Laatst online: 19:35

SinergyX

____(>^^(>0o)>____

Om jou NL->EN->NL voorbeeld te gebruiken, toelichting op Retile:

NL Dit is een zin vertaald om te testen.
EN This is a phrase translated to test
NL Dit is een vertaalde zin om te testen

NL waarom is reverse engineering eigenlijk moeilijk?
EN why reverse engineering is really difficult?
NL waarom reverse engineering is echt moeilijk?

Het zijn minimale verschillen, voor ons nog steeds 'redelijk' te lezen, maar in programmeertaal zou dit een wereld van verschil zijn.

Nog 1 keertje.. het is SinergyX, niet SynergyX
Im as excited to be here as a 42 gnome warlock who rolled on a green pair of cloth boots but was given a epic staff of uber awsome noob pwning by accident.


  • Foamy
  • Registratie: November 2006
  • Laatst online: 24-11 17:20

Foamy

Fulltime prutser

Rekcor schreef op woensdag 11 augustus 2010 @ 10:58:
Als dat zo is, waarom is dan het terugvertalen zo ingewikkeld?
Als ik deze zin als voorbeeld door een vertaler heen haal (NL->EN->NL) dan krijg je dit:
Als dat deze manier is, waarom is ingewikkeld terugvertalen dan deze manier?
Wat was er nou eenvoudig?

blub


  • Noxious
  • Registratie: Juli 2002
  • Laatst online: 28-11 14:32
Functienamen gaan verloren, comments gaan verloren, variabelenamen gaan verloren, enz enz

en bijv:

code:
1
2
3
4
5
6
function optellen($getal1, $getal2){
   $uitkomst = $getal1 + $getal2;
   return $uitkomst;
}
print(optellen(1,3));
print(optellen(8,12));


Zou best na het compileren en reverse engineren kunnen terugkomen als:
code:
1
2
3
4
5
6
7
8
$a = 1;
$b = 3;
$c = $a + $b;
print($c);
$d = 8;
$e = 12;
$f = $d + $e;
print($f);

  • Paitor
  • Registratie: Maart 2001
  • Laatst online: 18-01 12:37

Paitor

rages doen :P

Het moeilijkste aan programmeren (mijns inziens) is om ervoor te zorgen dat je nette, leesbare, gedocumenteerde code maakt. Anders kan een tweede programmeur jouw code nooit doorgronden. Een computer heeft maling aan onze menselijke problemen en hoeft het grotere geheel nooit te begrijpen, slechts regels uit te voeren. De compiler is dus meer ook een grote regelschrijver, dan dat deze structuur moet behouden zoals wij deze gewend zijn.

Als je reverse engineering op de simpelste wijze toepast, dan kan iedereen het lezen, maar kost het jaren om het totale plaatje goed te doorgronden. Vergelijk het met een archeologische opgraving. Je weet dat er een skelet ligt van een dino, of de resten van het gebouw. Maar om zeer specifieke vragen te beantwoorden zul je maanden onderzoek moeten doen.

Wellicht kan je door middel van patroonherkenning stukken machinecode herkennen die wijzen op een bepaalde procedure, object of klasse en die zo in een keer reverse engineren, met het juiste commentaar. Dat maakt de code dan een stuk beter leesbaar.

Live Life to the Max | Kom op konijntje doe maar huppele wiebele


  • _JGC_
  • Registratie: Juli 2000
  • Laatst online: 20:33
Noxious schreef op woensdag 11 augustus 2010 @ 11:24:
Functienamen gaan verloren, comments gaan verloren, variabelenamen gaan verloren, enz enz

en bijv:

code:
1
2
3
4
5
6
function optellen($getal1, $getal2){
   $uitkomst = $getal1 + $getal2;
   return $uitkomst;
}
print(optellen(1,3));
print(optellen(8,12));


Zou best na het compileren en reverse engineren kunnen terugkomen als:
code:
1
2
3
4
5
6
7
8
$a = 1;
$b = 3;
$c = $a + $b;
print($c);
$d = 8;
$e = 12;
$f = $d + $e;
print($f);
Zou best kunnen ja, afhankelijk van of de functie wordt geexporteerd en hoe de compiler optimaliseert. Je hebt bijvoorbeeld dingen als loop-unrolling, heb je in je code een for-loopje van 1 tot 10, maar in de gegenereerde machine code doet ie gewoon 10x hetzelfde met net iets andere input.

Wat betreft de variabelenamen valt het vaak mee overigens, het is maar net in hoeverre debugging eruit gestript is. Als ik onder linux met gdb een programma debug die gestript is met --strip-debug, dan kan ik nog wel zien welke functienamen het zijn, maar kan ik verder geen details achterhalen. Draai ik gdb met een programma dat gestript is met --strip-unneeded, dan kan ik de functienamen niet meer achterhalen en zie ik alleen nog maar dat het crasht.

  • kluyze
  • Registratie: Augustus 2004
  • Niet online
Noxious schreef op woensdag 11 augustus 2010 @ 11:24:
Functienamen gaan verloren, comments gaan verloren, variabelenamen gaan verloren, enz enz

en bijv:

code:
1
2
3
4
5
6
function optellen($getal1, $getal2){
   $uitkomst = $getal1 + $getal2;
   return $uitkomst;
}
print(optellen(1,3));
print(optellen(8,12));


Zou best na het compileren en reverse engineren kunnen terugkomen als:
code:
1
2
3
4
5
6
7
8
$a = 1;
$b = 3;
$c = $a + $b;
print($c);
$d = 8;
$e = 12;
$f = $d + $e;
print($f);
Als ik me goed herinner kan je aan de structuur van ASM (of zelfs machine code) zien welke delen van de code functies zijn, aangezien een functie een stukje code is wat apart staat en waar een branch naar toe springt. Bij het eindigen van de functie kan eventueel het resultaat terug gegeven worden en kan een branch naar de oorspronkelijke positie gedaan worden. Ook gaat dan de program counter bijgehouden worden etc.
Het lijkt me niet dat in de gecompileerde bestanden elke functie volledig uitgeschreven is voor elke keer deze aangeroepen wordt.
De functies lijkt me niet zo een probleem, dan naam van de functies en variabelen ben je kwijt maar ook dat lijkt me geen zware uitdaging.

Wat me eerder lijkt wat zwaar wordt zijn bepaalde gegevens structuren, hoe weet je hoe een bepaalde classe er uit zag, wat voor methodes had die en welke properties. Zaken als een struct, welke variabelen zaten daar in en hoe zit het met de types van de variabelen. Kan je in de computer code zien wat voor resolutie een variabele heeft. Bv het verschil tussen een double en een float, die aan andere precisie heeft.

Als je bij het compilen andere software gebruikt is het resultaat natuurlijk ook anders, een gcc/g++ zal een ander resultaat geven als een borland c++ of een visual c++ compiler. Al geeft dat niet altijd een probleem, het meeste verschil zit in de optimalisaties ed. en als die optimalisaties al in de (reverse engineerde) broncode zitten dan is dat geen probleem, zolang de code maar terug compileert en hetzelfde resultaat geeft.

[ Voor 19% gewijzigd door kluyze op 11-08-2010 11:40 ]


  • Standeman
  • Registratie: November 2000
  • Laatst online: 20:25

Standeman

Prutser 1e klasse

dit topic past beter in de devschuur, dus SG >> SEA

The ships hung in the sky in much the same way that bricks don’t.


  • Henk007
  • Registratie: December 2003
  • Laatst online: 06-04 00:29
Noxious schreef op woensdag 11 augustus 2010 @ 11:24:
Functienamen gaan verloren, comments gaan verloren, variabelenamen gaan verloren, enz enz

en bijv:

code:
1
2
3
4
5
6
function optellen($getal1, $getal2){
   $uitkomst = $getal1 + $getal2;
   return $uitkomst;
}
print(optellen(1,3));
print(optellen(8,12));


Zou best na het compileren en reverse engineren kunnen terugkomen als:
code:
1
2
3
4
5
6
7
8
$a = 1;
$b = 3;
$c = $a + $b;
print($c);
$d = 8;
$e = 12;
$f = $d + $e;
print($f);
Een optimaliserende compiler maakt er van:
code:
1
2
print (4);
print(20);


Al het overige is overbodig ;)

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
kluyze schreef op woensdag 11 augustus 2010 @ 11:38:
[...]
Als ik me goed herinner kan je aan de structuur van ASM (of zelfs machine code) zien welke delen van de code functies zijn, aangezien een functie een stukje code is wat apart staat en waar een branch naar toe springt. Bij het eindigen van de functie kan eventueel het resultaat terug gegeven worden en kan een branch naar de oorspronkelijke positie gedaan worden. Ook gaat dan de program counter bijgehouden worden etc.
Het lijkt me niet dat in de gecompileerde bestanden elke functie volledig uitgeschreven is voor elke keer deze aangeroepen wordt.
De functies lijkt me niet zo een probleem, dan naam van de functies en variabelen ben je kwijt maar ook dat lijkt me geen zware uitdaging.
Er zal over het algemeen een standaard aangehouden worden voor een functieaanroep ja. Er zullen wat variabelen op de stack gezet worden, naar het juiste adres gesprongen worden, en weer terug gesprongen. Maar er zijn verschillende manieren waarop dat gedaan kan worden, en dat zal afhankelijk zijn van welke call-conventie er gebruikt word. Verder hoeft een dergelijke structuur ook niet perse in te houden dat er een functie-call gedaan word. Ook kunnen functie calls weg-geoptimaliseerd worden, en de code dus gewoon inline opgenomen worden.
Wat me eerder lijkt wat zwaar wordt zijn bepaalde gegevens structuren, hoe weet je hoe een bepaalde classe er uit zag, wat voor methodes had die en welke properties. Zaken als een struct, welke variabelen zaten daar in en hoe zit het met de types van de variabelen. Kan je in de computer code zien wat voor resolutie een variabele heeft. Bv het verschil tussen een double en een float, die aan andere precisie heeft.
Het is juist niet zo heel moeilijk om een redelijke inschatting te maken wat voor primitief data type iets is. Je kunt gewoon kijken hoe de variabele gebruikt word. Een 4-bytes floating point type, zal immers anders gebruikt worden dan een 8-bytes floating point type.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Noxious
  • Registratie: Juli 2002
  • Laatst online: 28-11 14:32
Henk007 schreef op woensdag 11 augustus 2010 @ 11:42:
[...]

Een optimaliserende compiler maakt er van:
code:
1
2
print (4);
print(20);


Al het overige is overbodig ;)
Uiteraard, ik ging er stieken vanuit dat de input echt variabel was :+

En zoals hierboven al aangegeven, functies blijven ook vaak behouden, ligt vaak ook wel aan de optimalisaties van je compiler. Als het sneller lijkt te zijn om de functies niet te gebruiken dan kunnen die ook worden gestript.

Daarnaast is e.e.a. ook erg afhankelijk van de gebruikte taal en compiler natuurlijk, en het opgegeven optimalisatieniveau.

Zie bijv ook de optimalisatieniveau's van gcc: http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

Edit: als prima voorbeeld voor hierboven, er is dus een optie '-finline-small-functions' voor gcc :)
Deze wordt gebruikt op niveau -O2, wat afaik een beetje 'de standaard' is.

Het leuke is wel dat sommige programma's niet meer werken als je ze compiled met sommige optimalisatieopties, bijv -O3 laat veel dingen stuq gaan. :P

[ Voor 8% gewijzigd door Noxious op 11-08-2010 12:06 ]


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Noxious schreef op woensdag 11 augustus 2010 @ 11:24:
Het leuke is wel dat sommige programma's niet meer werken als je ze compiled met sommige optimalisatieopties, bijv -O3 laat veel dingen stuq gaan. :P
Met name als je zelf vuile dingen doet. Zoals bijvoorbeeld een float pointer en een int pointer naar hetzelfde geheugen laten wijzen, een float wegschrijven en dan die als int teruglezen. Met opties als -fstrict-aliasing (zit al in -O2) vertel je de compiler dat hij er vanuit kan gaan dat pointers van verschillende typen nooit naar hetzelfde geheugen zullen wijzen. Dit betekent dus in bovenstaand voorbeeld dat je zegt dat de compiler er vanuit kan gaan dat data waar de int pointer naar wijst niet verandert als je de float schrijft, en dus kan hij bij het inlezen eventueel een oude waarde gebruiken.

Desalniettemin is dit een hele belangrijke optimalisatie, omdat de compiler anders bijna nooit waarden in registers kan houden zolang je met pointers bezig bent, omdat er altijd een mogelijkheid is dat de pointers elkaar overlappen (oftewel er treedt "aliasing" op)

[ Voor 78% gewijzigd door .oisyn op 11-08-2010 12:16 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
kluyze schreef op woensdag 11 augustus 2010 @ 11:38:
[...]

Als ik me goed herinner kan je aan de structuur van ASM (of zelfs machine code) zien welke delen van de code functies zijn, aangezien een functie een stukje code is wat apart staat en waar een branch naar toe springt. Bij het eindigen van de functie kan eventueel het resultaat terug gegeven worden en kan een branch naar de oorspronkelijke positie gedaan worden.
En dan hebben we het nog niet over stukken code die worden geoptimaliseerd voor branche prediction, loop-unrolls (unwinding) etc. Zaken waar een compiler meteen ziet dat ze makkelijker/beter/efficienter kunnen maar die voor ons haast onbegrijpelijk zijn.
kluyze schreef op woensdag 11 augustus 2010 @ 11:38:
Ook gaat dan de program counter bijgehouden worden etc.
Doorgaans doet de CPU dat (thank god) zelf :P
Anders krijg je:

instructie
program_counter++
instructie
program_counter++
instructie
program_counter++

en eigenlijk dat nog niet eens wat na iedere instructie zou je de program counter moeten ophogen, nu doe je dat alleen op de even instructies... :P
kluyze schreef op woensdag 11 augustus 2010 @ 11:38:
Het lijkt me niet dat in de gecompileerde bestanden elke functie volledig uitgeschreven is voor elke keer deze aangeroepen wordt.
In bepaalde gevallen kan dat wel degelijk het geval zijn.
kluyze schreef op woensdag 11 augustus 2010 @ 11:38:
De functies lijkt me niet zo een probleem, dan naam van de functies en variabelen ben je kwijt maar ook dat lijkt me geen zware uitdaging.
Bij een "hello world" niet, maar mikker eens een Word.exe of Firefox.exe of whatnot door een disassembler en probeer van die brij nog eens wat zinnigs te maken. Dat doe je niet op een middagje ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Noxious
  • Registratie: Juli 2002
  • Laatst online: 28-11 14:32
.oisyn schreef op woensdag 11 augustus 2010 @ 12:04:
[...]

Met name als je zelf vuile dingen doet. Zoals bijvoorbeeld een float pointer en een int pointer naar hetzelfde geheugen laten wijzen, een float wegschrijven en dan die als int teruglezen. Met opties als -fstrict-aliasing (zit al in -O2) vertel je de compiler dat hij er vanuit kan gaan dat pointers van verschillende typen nooit naar hetzelfde geheugen zullen wijzen. Dit betekent dus in bovenstaand voorbeeld dat je zegt dat de compiler er vanuit kan gaan dat data waar de int pointer naar wijst niet verandert als je de float schrijft, en dus kan hij bij het inlezen eventueel een oude waarde gebruiken.

Desalniettemin is dit een hele belangrijke optimalisatie, omdat de compiler anders bijna nooit waarden in registers kan houden zolang je met pointers bezig bent, omdat er altijd een mogelijkheid is dat de pointers elkaar overlappen (oftewel er treedt "aliasing" op)
Mja, ik heb een keer LFS (http://www.linuxfromscratch.org/) doorgewerkt en daar komt m'n meeste "compilatiekennis" vandaan. Ik heb daar iig gemerkt dat er een hoop zaken in de linux sources zitten die met -O2 al breken :P

  • kluyze
  • Registratie: Augustus 2004
  • Niet online
Woy schreef op woensdag 11 augustus 2010 @ 11:47:
[...]

Er zal over het algemeen een standaard aangehouden worden voor een functieaanroep ja. Er zullen wat variabelen op de stack gezet worden, naar het juiste adres gesprongen worden, en weer terug gesprongen. Maar er zijn verschillende manieren waarop dat gedaan kan worden, en dat zal afhankelijk zijn van welke call-conventie er gebruikt word. Verder hoeft een dergelijke structuur ook niet perse in te houden dat er een functie-call gedaan word. Ook kunnen functie calls weg-geoptimaliseerd worden, en de code dus gewoon inline opgenomen worden.
Dat kan ja dat door optimalisatie de functie weg is, maar dan gok ik dat of de functie maar 1 keer gebruikt word of de functie is eventueel zo kort dat een function call meer plaats/tijd in beslag neemt. Maar geeft dat dan een probleem om te reverse engineeren? Ik vind van niet.
Het is juist niet zo heel moeilijk om een redelijke inschatting te maken wat voor primitief data type iets is. Je kunt gewoon kijken hoe de variabele gebruikt word. Een 4-bytes floating point type, zal immers anders gebruikt worden dan een 8-bytes floating point type.
Ik heb zelf ooit een 'hoe werkt een compiler for dummies' gezien maar echt thuis in die materie ben ik natuurlijk niet. Maar ik had het eerder op de zaken als weten hoe een classe er uit ziet ed. Over de resolutie van een variabele kan je gelijk hebben, al zou ik zo onmiddellijk niet weten hoe je dit uit de machine code zou kunnen halen.

[ Voor 154% gewijzigd door kluyze op 11-08-2010 14:48 ]


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
kluyze schreef op woensdag 11 augustus 2010 @ 12:30:
[...]
Maar ik had het eerder op de zaken als weten hoe een classe er uit ziet ed.
Ook dat lijkt me niet eens extreem moeilijk ( Al zal het lastig zijn om het 100% goed te doen ), aangezien variabelen van een class meestal gewoon opvolgend opgeslagen zullen zijn, en dus ook in een blok op de stack gezet zullen worden. Aan de hand van het gebruik van het geheugen denk ik dat je nog best een hoop kunt afleiden. De member functions zijn misschien wat lastiger te achterhalen.
offtopic:
Per ongeluk op edit gedrukt in plaats van quote :$

[ Voor 5% gewijzigd door Woy op 11-08-2010 12:59 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • frickY
  • Registratie: Juli 2001
  • Laatst online: 27-11 09:24
SinergyX schreef op woensdag 11 augustus 2010 @ 11:18:
Om jou NL->EN->NL voorbeeld te gebruiken, toelichting op Retile:

NL Dit is een zin vertaald om te testen.
EN This is a phrase translated to test
NL Dit is een vertaalde zin om te testen
Extremer voorbeeld die het probleem wellicht beter illustreert.
EN: I want to kiss you
NL: Ik wil je kussen
EN: I want your pillow

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 11:35

Janoz

Moderator Devschuur®

!litemod

kluyze schreef op woensdag 11 augustus 2010 @ 12:30:
[...]
Dat kan ja dat door optimalisatie de functie weg is, maar dan gok ik dat de functie maar 1 keer gebruikt wordt.
Fout gegokt. Inlining gebeurt meestal bij functies veel (in de runtime context) aangeroepen worden. Door de functie aanroep overhead weg te halen is de programmatuur een stuk efficienter. Maar doordat er een enorme hoeveelheid code duplicatie is, is het voor de mens een stuk slechter leesbaar en onderhoudbaar. Voor de comupter maakt die duplicatie niet uit aangezien de computer het alleen maar uit hoeft te voeren.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • kluyze
  • Registratie: Augustus 2004
  • Niet online
Je quote wel heel gemakkelijk maar een deel van mijn uitleg :p Maar mijn fout om daar een leesteken te zetten. En omwille van een 'foutje' van je collega kan ik mijn post niet meer aanpassen. Hmm, lijkt wel een complot! :) Hmm, ik dacht dat indien een mod een post aanpast dat deze niet meer door de user veranderd kan worden?

Maar gaat dat optimaliseren ook gebeuren indien je grote functies hebt waar de overhead van de call minder belangrijk wordt maar waar de functie een heel groot aantal keer wordt aangeroepen? Dan zou een optimalisatie weinig winst geven maar een grote executable krijgen. Welke dan ook weer trager werkt aangezien bij het uitvoeren meer data van de hdd naar het geheugen geladen moet worden.

[ Voor 8% gewijzigd door kluyze op 11-08-2010 14:49 ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Janoz schreef op woensdag 11 augustus 2010 @ 13:16:
Voor de comupter maakt die duplicatie niet uit aangezien de computer het alleen maar uit hoeft te voeren.
Tenzij je voor bestandsgrootte wilt optimaliseren ;) Wat gelijk de complexiteit van het probleem weer toe doet nemen, want het is al lastig (onmogelijk om perfect te doen lijkt me) om de code te decompileren als je de compiler en diens flags weet, maar als je ook nog eens niet weet welke optimalisaties mochten worden uitgevoerd en welke compiler er bezig was?

Zelfs een vereenvoudigde variant van dit probleem is al lastig, probeer maar eens een "minified" stuk javascript te lezen, de variant waarbij de variabele namen vervangen zijn door kortere dan uiteraard. Het is al knap lastig om dat terug te vertalen naar een variant met leesbare variabele- en functienamen, terwijl je daar over het algemeen de structuur van de taal in de minified variant vrij goed terug kan vertalen (dat whitespace een beetje anders geplaatst wordt boeit niet zo voor de leesbaarheid).

[ Voor 30% gewijzigd door ACM op 11-08-2010 19:37 ]


  • .oisyn
  • Registratie: September 2000
  • Nu online

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik zie ook regelmatig dat functies die binair gezien hetzelfde zijn gemerged worden. Zit je de debuggen, wat dan sowieso al niet lekker gaat aangezien het een geoptimaliseerde executable is, springt ie ineens een compleet ongerelateerde functie in die toevallig hetzelfde doet (granted, dit soort functies zijn dan over het algemeen wel vrij simpel)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Paitor schreef op woensdag 11 augustus 2010 @ 11:28:
Het moeilijkste aan programmeren (mijns inziens) is om ervoor te zorgen dat je nette, leesbare, gedocumenteerde code maakt. Anders kan een tweede programmeur jouw code nooit doorgronden. Een computer heeft maling aan onze menselijke problemen en hoeft het grotere geheel nooit te begrijpen, slechts regels uit te voeren. De compiler is dus meer ook een grote regelschrijver, dan dat deze structuur moet behouden zoals wij deze gewend zijn.
Zeker waar. Maar aan de andere kant... ik heb wel stukken code gezien die na decompilatie er waarschijnlijk beter uit gaan zien :+

@TS: het probleem is simpelweg dat compilers proberen code te produceren die zo snel mogelijk is. En dat betekend al snel dat code samengevoegd wordt, weggehaald wordt, etc... Dat is een vertaling die maar 1 kant op kan en dat zal je dus nooit meer kunnen herleiden.

Zoals hier ook al aangegeven is met het "optellen" voorbeeld kan het heel goed zijn dat de code maar 1 kant op werkt. En als dat het geval is dan zal je nooit meer je mooie nette code eruit kunnen krijgen. Of zelfs maar leesbare code...

Blog [Stackoverflow] [LinkedIn]


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
Bedankt allemaal! Weer een heleboel geleerd :).

Ben ik wel benieuwd hoe ze zo'n compiler maken, want dat lijkt me een ingewikkeld stuk programmeersel.

[ Voor 53% gewijzigd door Rekcor op 16-08-2010 08:38 ]


  • HuHu
  • Registratie: Maart 2005
  • Niet online
Rekcor schreef op maandag 16 augustus 2010 @ 08:36:
Bedankt allemaal! Weer een heleboel geleerd :).

Ben ik wel benieuwd hoe ze zo'n compiler maken, want dat lijkt me een ingewikkeld stuk programmeersel.
Ik zou zeggen, ga studeren: Compilerconstructie en Seminar Advanced compiler construction.

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
Hehe, bedankt maar nee, heb het studentenleven al een tijdje achter me gelaten.

Het was meer een retorische vraag :).

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 16-10 10:47
.oisyn schreef op woensdag 11 augustus 2010 @ 20:58:
Ik zie ook regelmatig dat functies die binair gezien hetzelfde zijn gemerged worden. Zit je de debuggen, wat dan sowieso al niet lekker gaat aangezien het een geoptimaliseerde executable is, springt ie ineens een compleet ongerelateerde functie in die toevallig hetzelfde doet (granted, dit soort functies zijn dan over het algemeen wel vrij simpel)
Dat lijkt me echt vaag...verklaarbaar natuurlijk als je weet dat het kan gebeuren. Maar als je dat niet weet, kan me voorstellen dat je dan echt zoiets hebt van: WTF... 8)7

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
SinergyX schreef op woensdag 11 augustus 2010 @ 11:18:
Om jou NL->EN->NL voorbeeld te gebruiken, toelichting op Retile:

NL Dit is een zin vertaald om te testen.
EN This is a phrase translated to test
NL Dit is een vertaalde zin om te testen

NL waarom is reverse engineering eigenlijk moeilijk?
EN why reverse engineering is really difficult?
NL waarom reverse engineering is echt moeilijk?

Het zijn minimale verschillen, voor ons nog steeds 'redelijk' te lezen, maar in programmeertaal zou dit een wereld van verschil zijn.
Als je met voorbeelden komt prima, maar vertaal zinnen van wel correct :)
frickY schreef op woensdag 11 augustus 2010 @ 13:07:
Extremer voorbeeld die het probleem wellicht beter illustreert.
EN: I want to kiss you
NL: Ik wil je kussen
EN: I want your pillow
Inderdaad, veel beter voorbeeld. Het gaat er niet om dat een compiler 'fouten' maakt, computers maken nooit fouten. Het gaat er om dat een 'woord' vaak meerderere vertalingen heeft en een decompiler maar moet 'gokken'.
kluyze schreef op woensdag 11 augustus 2010 @ 11:38:
Als ik me goed herinner kan je aan de structuur van ASM (of zelfs machine code) zien welke delen van de code functies zijn, aangezien een functie een stukje code is wat apart staat en waar een branch naar toe springt.
FYI: Een van de meest simpele optimalisaties die een compiler (al dan niet runtime in het geval vane en JIT compiler) kan doen is het inlinen van simpele functies. Iets als:

C:
1
2
3
4
5
6
7
8
9
10
public int function(int a)
{
    a = add(a, 10);
    return a;
}

private int add(int val, int toAdd)
{
    return val + toAdd;
}


Wordt dan:

C:
1
2
3
4
public int function(int a)
{
    return a + 10;
}


Geen branch meer dus naar een andere functie.

[ Voor 50% gewijzigd door Hydra op 17-08-2010 14:03 ]

https://niels.nu

Pagina: 1