Gezwungenen Sleep einbauen?

Hab hier ein Problem,
ich habe ein Programm, dass, weil keine Sleeps eingebaut sind,
immer 90% cpu auslastung verursacht. Es ist in Delphi gecoded!
Kann ich das per Olly verschönern? Und wenn ja, wie :-)

Vielen Dank schonmal ;)

Hab mal was gerippt:

Code:
  PUSH 0C8
  CALL Sleep

Edit: Jau so geht's,
eben noch ne Code Cave gesucht, und nun ist die CPU-Auslastung bei schönen 0% :-)
 
Wenn Du den "Flaschenhals" hast wäre wohl am einfachsten:

per IID-King Sleep API hinzufügen (sollte aber eher schon vorhanden sein, weil bei Borland-VCL Zeug so ziemlich alles genutzt wird ;) )

In Olly eine "Codecave" suchen - also freien Breich im Code, der mit 00 gefüllt ist (z.B am Ende der Codesection, wo der Linker wegen Section-Ausrichtung öfters einen 00 Bereich macht) ). Aber aufgepasst: nicht zu früh freuen und irgendwo dann den Code reinschreiben, denn es gibt sowohl virtuelles wie physikalische Section-Ausrichtung - also einmal im File/Exe selber und einmal im Speicher, wenn die Executable läuft. Dabei ist der physikalische Wert meistens viel kleiner als der virtuelle (öfters 4096 und 512 Byte) - das heißt im Speicher sieht man paar tausend 00 und physikalisch sind nur einige dutzend oder hundert vorhanden. Schreibt man seinen Code in den Bereich rein, der physikalisch nicht existiert, kann man die Änderung nicht abspeichern ;)

In die "Codecave" dann gewünschten Code reinschreiben (entweder den "Sleep" Aufruf, falls Sleep schon im Programm vorhanden ist oder per LoadLibrary und GetProcAddress "Sleep" Adresse herausbekommen (oder vorher per IDD King hinzufügen).

Jetzt noch aus dem "Flaschenhals"-Code an geeignerter Stelle einen Jump zum eingefügten Code machen und ans Ende des eingefügten Codes einen JMP zurück.

Sollte sich keine Codecave finden lassen (was ich bei einem Standard-Delphi Programm nicht gleube ;) ) kann man auch mit LordPE oder ToPo einen neue Section hinzufügen, die man dann nach belieben nutzen kann.

Die Herausforderung wäre allerdings den Verursacher des Übels zu finden - also den Flaschenhals.Je nach Programm und Code imho nicht ganz einfach. Denn wenn es die Delphi-interenen Bibliotheken nutzt wird man nur schwer per tracing darauf kommen - und die Delphiinternen Sachen zu patchen, die auch an anderen Codestellen aufgerufen werden könnte Nebeneffekte haben. Dabei wird man öfters die "Auswirkunen" (also derade ausgeführten Code) sehen, als den Verursacher (den Aufrufer) - jedoch sollte nach einiger Zeit (laufen lassen, pause, schauen wo man ist, anschauen von Call-stack (ALT+K) ) sich das einkreisen lassen.

EDIT: toll, da schreibt man was und Du wirst in der Zeit schon fertig
Ich lass es mal stehen, damit es nicht ganz umsonst war und vielleicht paar Google Bots was davon haben ;)

PS: auch beachtet dass Olly einen direkten "CALL Sleep" als Call auf die Kerneladresse umsetzt (also direkt die Adresse reinschreibt und nicht etwa per IAT Umweg)? Sonst gibt es nach dem nächsten größeren Update oder auf einem anderen PC eventuell Probleme, weil die Adresse sich ändert bzw. verschiebt.
 
Original von CDW
Wenn Du den "Flaschenhals" hast wäre wohl am einfachsten:

per IID-King Sleep API hinzufügen (sollte aber eher schon vorhanden sein, weil bei Borland-VCL Zeug so ziemlich alles genutzt wird ;) )

In Olly eine "Codecave" suchen - also freien Breich im Code, der mit 00 gefüllt ist (z.B am Ende der Codesection, wo der Linker wegen Section-Ausrichtung öfters einen 00 Bereich macht) ). Aber aufgepasst: nicht zu früh freuen und irgendwo dann den Code reinschreiben, denn es gibt sowohl virtuelles wie physikalische Section-Ausrichtung - also einmal im File/Exe selber und einmal im Speicher, wenn die Executable läuft. Dabei ist der physikalische Wert meistens viel kleiner als der virtuelle (öfters 4096 und 512 Byte) - das heißt im Speicher sieht man paar tausend 00 und physikalisch sind nur einige dutzend oder hundert vorhanden. Schreibt man seinen Code in den Bereich rein, der physikalisch nicht existiert, kann man die Änderung nicht abspeichern ;)

In die "Codecave" dann gewünschten Code reinschreiben (entweder den "Sleep" Aufruf, falls Sleep schon im Programm vorhanden ist oder per LoadLibrary und GetProcAddress "Sleep" Adresse herausbekommen (oder vorher per IDD King hinzufügen).

Jetzt noch aus dem "Flaschenhals"-Code an geeignerter Stelle einen Jump
zum eingefügten Code machen und ans Ende des eingefügten Codes einen JMP zurück.

Sollte sich keine Codecave finden lassen (was ich bei einem Standard-Delphi Programm nicht gleube ;) ) kann man auch mit LordPE oder ToPo einen neue Section hinzufügen, die man dann nach belieben nutzen kann.

Die Herausforderung wäre allerdings den Verursacher des Übels zu finden - also den Flaschenhals.Je nach Programm und Code imho nicht ganz einfach. Denn wenn es die Delphi-interenen Bibliotheken nutzt wird man nur schwer per tracing darauf kommen - und die Delphiinternen Sachen zu patchen, die auch an anderen Codestellen aufgerufen werden könnte Nebeneffekte haben. Dabei wird man öfters die "Auswirkunen" (also derade ausgeführten Code) sehen, als den Verursacher (den Aufrufer) - jedoch sollte nach einiger Zeit (laufen lassen, pause, schauen wo man ist, anschauen von Call-stack (ALT+K) ) sich das einkreisen lassen.

EDIT: toll, da schreibt man was und Du wirst in der Zeit schon fertig
Ich lass es mal stehen, damit es nicht ganz umsonst war und vielleicht paar Google Bots was davon haben ;)

PS: auch beachtet dass Olly einen direkten "CALL Sleep" als Call auf die Kerneladresse umsetzt (also direkt die Adresse reinschreibt und nicht etwa per IAT Umweg)? Sonst gibt es nach dem nächsten größeren Update oder auf einem anderen PC eventuell Probleme, weil die Adresse sich ändert bzw. verschiebt.

Puh das ist ja mal nen langer Text :-)

Ja die Uhrsache hab ich gefunden, weil wenn das Programm nix tut,
benutzt es andauernd einen Jump der nur 3 Funktionen Lang ist,
das ist sehr CPU-Aufwändig ;-)
Ich gucke mir mal dieses IID-King an.

Also jetzt callt er direkt meine Kerneladresse....
Ich weiss jetzt nicht direkt wie ich da durch Umwege über die Iat drankomme
Ich probier es jetzt mal auf meiner VM-Machine.

Wenn es da geht, lass ich es so :D

edit: das ist ja mal nen nützliches Tool,
danke für den Hinweis :-9

Werd ich in Zukunft sicher mal Verwendung für haben :D

edit2: Leider hasst du recht, es funktioniert auf der VM nicht
 
@ CDW

Wollt nur kurz sagen, dass ich deine Mühen zu schätzen weiß! Ich hab zwar momentan keine Verwendung dafür, und mir fehlt wahrscheinlich noch das nötige Wissen um es anzuwenden aber trotzdem vielen Dank für das Tutorial! Jetzt weiß ich wo ich was, wie machen muss wenn es mal soweit ist!

Also danke fürs Nicht-Löschen ;)
 
Ich weiss jetzt nicht direkt wie ich da durch Umwege über die Iat drankomme

Ich habe es gerade mit einem zufälligen Delphi-Programm ausprobiert: per STRG+N (oder Rechtsklick "Search for ->Name (labels) in current module") sich die genutzten APIs auflisten lassen - und Sleep war in meinen beiden Beispielprogrammen dabei.

Wenn man dann sich die Verwendung im Code anschaut (also die "Find references to import" bzw. Enter in dieser Liste wählt) kommt man zu der Codestelle und sieht sowas:
Code:
0043B2FA   |.  52                                        |PUSH EDX                                           ; /Timeout = 2147353348. ms
0043B2FB   |.  E8 14AEFCFF                               |CALL <JMP.&kernel32.Sleep>                         ; \Sleep

Wer auf den Call geht (markieren und Enter), landet in der JMP Tabelle
Code:
00406114    $- FF25 1CD24400                             JMP DWORD PTR DS:[<&kernel32.Sleep>]                ;  kernel32.Sleep
Das ist jetzt eine der Delphieigenarten - manche Linker machen keine "Zwischentabelle", manche wie der von MASM oder Borland eben doch.

Für Deinen Code kannst Du dann auch "CALL Adresse_von_dem_Sleep-JMP" (im Beispiel wäre das CALL 00406114)
oder Du schaust nach, wo die IAT liegt (Rechtlick auf den JMP und "Follow in Dump" oder einfach Leertaste betätigen, dann zeigt Olly den "richtigen" Code an, anstatt den durch den Namen zu erstetzen - in meinem Fall ist es :
JMP DWORD PTR DS:[44D21C]
Also ist die IAT an 44XXXx und die Sleep-Api Adresse befindet sich immer (auf jedem System) an der 44D21C. Für Deinen Fall wäre also entweder der "CALL 406114" oder "CALL [44D21C]" angebracht (bzw die entsprechenden Adressen für das Programm).
Oder IID bemühen - der erstellt sogar eine TXT Datei, wo die Adressen der hinzugefügten Funktionen stehen.

PS: die Olly-Anweisungsbeschreibungen sind jetzt nicht speziell an sd333221 gerichtet (also nicht böse sein ;) )


@Cyberm@ster: falls Du Dich für PE-Format (wofür einzelne Sachen wie z.B IAT oder PE-Headers in einer Windowsexecutable da sind) und allgemein fürs "Rumstochern in Exen" interessierst, kann ich http://cdw.de.vu/loesungen.htm (die letzten beiden Lösungen bzw. Direktlinks: http://cdw.de.vu/sb6.zip http://cdw.de.vu/loesung_6.zip) anbieten.
Wobei das gleichzeitig eine Einführung ins Unpacking ist und beide Artikel auf die Anfänger-Gruppe zielen (Erklärungen zu Ollyaktionen und viele Screenshots) *werbung mach*
 
Zurück
Oben