Hey Leute, ich bins mal wieder
Dieses Mal jedoch mit einem kleinen "Progrämmchen" für die Programmierer unter euch..
Ich hab für die Analyse einer P-Server-Exe ein kleines Programm geschrieben, das nach den Referenzen auf eine bestimmte Adresse sucht
Z.B. von wo aus eine Adresse 0xXXXXXXXX gecallt/gepusht/gejumpt wird
Dazu hab ich 2 Funktionen geschrieben, einmal
Code:
void* SearchByteArray(unsigned char* searchstr, DWORD startaddr, DWORD endaddr, DWORD len);
sowie
Code:
void GetReferenceArray(unsigned char* refbyte, DWORD refaddress, unsigned char typebyte);
Die erste Funktion sucht ein Array von unsigned chars im Memory von Start- zu Endadresse, die 2. Funktion wandelt die gefundene Adresse in ein unsigned char-Array um, welches dann gesucht werden kann
So gesehen wird also die 2. Funktion vor der ersten benutzt
Die vollständige Headerdatei mitsamt Dokumentation gibts hier:
Code:
#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
/*
-----------------------------------------------------------------------------------------------------
| SearchByteArray - © by Padmak, 2011 (http://padmak.de/) |
| |
| Parameter: |
| unsigned char* searchstr - A Pointer to a Byte-Array |
| DWORD startaddr - The address where the search should be started |
| DWORD endaddr - The address where the search should be stopped |
| DWORD len - The size of the Byte-Array |
| mask - A mask to apply to the refbyte-array. (Only SearchByteArrayWC) |
| The searchstr-array is compared to the mask-array. |
| The algorithm can find {0x90, 0x90} with the mask {0x00, 0x00} |
| But if there is an 0x01 at one specific byte-position, like this: {0x01, 0x00}, every |
| array like {0x12, 0x90} or {0x51, 0x90} is found. |
| |
| Example for finding static arrays: |
| unsigned char searchbytes[5] = {0x90, 0x90, 0x90, 0x90, 0x90}; |
| void* address = SearchByteArray(searchbytes, 0x400000, 0x700000, sizeof(searchbytes)); |
| |
| Example for finding static arrays with wildcards: |
| unsigned char searchbytes[5] = {0x90, 0x90, 0x90, 0x90, 0x90}; |
| unsigned char mask[5] = {1, 1, 0, 0, 0}; |
| void* address = SearchByteArrayWC(searchbytes, 0x400000, 0x700000, sizeof(searchbytes), mask);|
-----------------------------------------------------------------------------------------------------
*/
void* SearchByteArray(unsigned char* searchstr, DWORD startaddr, DWORD endaddr, DWORD len);
void* SearchByteArrayWC(unsigned char* searchstr, DWORD startaddr, DWORD endaddr, DWORD len, unsigned char* mask);
/*
-----------------------------------------------------------------------------------------------------
| GetReferenceArray - © by Padmak, 2011 (http://padmak.de/) |
| |
| Parameter: |
| unsigned char* refbyte = A pointer to an array of unsigned char with 5 Elements (!important!) |
| refaddress - The address for which the reference-byte-array should be created |
| typebyte - The first byte of the reference, e.g. 0x68 for PUSH |
| The important ones: |
| PUSH - 0x68 |
| CALL - 0xE8 |
| JMP - 0xE9 |
| |
| Example: |
| unsigned char push = {}; |
| GetReferenceArray(push, 0x005125AF, 0x68); |
| void* address = SearchByteArray(push, 0x400000, 0x700000, sizeof(push),); |
-----------------------------------------------------------------------------------------------------
*/
void GetReferenceArray(unsigned char* refbyte, DWORD refaddress, unsigned char typebyte);
#ifdef __cplusplus
}
#endif
#endif // __MAIN_H__
Nur kurze Erklärung:
Wenn man GetReferenceArray eine Adresse 0x11223344 übergibt und das ganze als PUSH haben möchte, sieht das übergebene Byte-Array so aus:
0x68, 0x44, 0x33, 0x22, 0x11
Da mich diese Funktionen etliches an Arbeit (und Hilfe/Nerven von tim66613) gekostet haben, gibts den Code davon nicht, ich hab euch aber eine minikleine (730 Byte) große statische Bibliothek gebaut, die ihr verwenden könnt
Im Anhang ist das Code::Blocks-Projekt, die fertige (bereits kompilierte) DLL für alle die nur kurz testen wollen sowie ein kleiner Beispiel-Code
Das Projekt sollte mit der neuesten Code::Blocks-Version (10.05) problemlos zu öffnen sein
Ich hoffe ich erreiche hier den ein oder anderen der es brauchen kann
Scheut euch nicht zu fragen (keine WAS ISD DAS WAS KAN DAS - Fragen, vernünftige!)
Update 13.11.2011:
Habe soeben eine neue Funktion eingebaut, namens "SearchByteArrayWC"
Diese Funktion nimmt als 5. Parameter ein unsigned char-Array.
Mit diesem Array kann man eine Wildcard-Funktion realisieren... ein Beispiel zur Veranschaulichung:
Code:
unsigned char searchbytes[5] = {0x90, 0x90, 0x90, 0x90, 0x90};
unsigned char mask[5] = {1, 1, 0, 0, 0};
void* address = SearchByteArrayWC(searchbytes, 0x400000, 0x700000, sizeof(searchbytes), mask);
searchbytes ist klar, das ist das Array nach dem gesucht werden soll
mask erkläre ich jetzt: eine 1 steht für überspringen, eine 0 steht für vergleichen.
Wenn also in mask eine 1 an einer Stelle steht, wird das zugehörige Byte in searchbytes einfach übersprungen, ohne es zu vergleichen
Ist beschissen zu erklären, aber ich hoffe es ist einigermaßen verständlich...
Das macht die Funktion viel flexibler, da dynamische Adressen jetzt einfach übersprungen werden können, statische Teile jedoch gewertet werden. Damit muss man nicht mehrmals hintereinander suchen (mein bisheriger Workaround) sondern kann es in einem erledigen
Ps: Das Passwort für beide Archive ist Padmak, Virustest gibts hier:
Padmak