Bytes entdecken in C

Der Compiler lässt mich nicht, was ist denn falsch:

DWORD findAddr(std::string mName, char * bytes, size_t len) {
	DWORD hModule = (DWORD)GetModuleHandleA(mName.c_str());
a:
	for (size_t j = hModule; j < hModule + (1024 * 1024); j++)
	{
		for (size_t i = 0; i < len; i++)
		{
			if (bytes** != *(char*)(j + i)) {
			a: continue;
			}
		}
		return j;
	}
	return 0;
}

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand Fehler C2045 "a": Neudefinition einer Bezeichnung

Du definierst eine goto Marke doppelt, sowas geht nicht in C.

Ich denke ich habs:

	bool done = false;
	for (size_t j = hModule; j < hModule + (1024 * 1024); j++)
	{
		done = true;
		for (size_t i = 0; i < len; i++)
		{
			if (bytes** != *(char*)(j + i)) {
				done = false;
				break;
			}
		}
		if (done)
			return j;
	}
	return 0;

Der erklärt es sehr nice:

( http://www.peacesoftware.de/ckurs11.html )


Das nächste wäre dann (gibt leider immer 2 auch):

char * hexToByteChar(std::string hex, char * buf) {
	std::stringstream ss;
	ss << std::hex << hex;
	for (size_t i = 0; i < hex.length(); i += 2)
	{
		unsigned int b;
		ss >> b;
		buf[i / 2] = b;
	}
	for (size_t i = 0; i < hex.length(); i += 2)
	{
		printf("%x ", buf[i / 2]);
	}
	printf("\n");
	return buf;
}

Hast du buf alloziert? Stellst du überhaupt sicher, dass du nicht außerhalb des Speicherbereichs von buf schreibst? Sieht nicht so aus. ich glaube aber doch das statt der dritten Codezeile doch so etwas gehört:

ss << hex;
ss >> std::hex;

Nunja, wenn man in C auf die Byteebene herunter geht, dann muss das der Aufrufer sicherstellen, in der Funktion ist das nicht möglich. Aber ja:

char buf[100]; hexToByteChar("5a5b5c02", buf); //findAddr("SciLexer.dll", buf, 8);

Ausgegeben wird immer 4x 2… komisch.
Hab jetzt gelesen, man bräuchte einen zweiten std::stringstream…

2 Hexziffern sind doch ein byte = ein char, richtig?

	std::stringstream ss;
	ss << std::hex << hex;
	std::stringstream ss2(ss);

Solche Fehlermeldungen mag ich(*):

Fehler (aktiv) E1776 Auf “Funktion “std::basic_stringstream<_Elem, _Traits, _Alloc>::basic_stringstream(const std::basic_stringstream<_Elem, _Traits, _Alloc> &) [mit _Elem=char, _Traits=std::char_traits, _Alloc=std::allocator]” (deklariert in Zeile 627 von “c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include\sstream”)” kann nicht verwiesen werden (ist eine gelöschte Funktion).

Fehler C2280 “std::basic_stringstream<char,std::char_traits,std::allocator>::basic_stringstream(const std::basic_stringstream<char,std::char_traits,std::allocator> &)” : Es wurde versucht, auf eine gelöschte Funktion zu verweisen

*: Ironie.

Der mit 172 Upvotes macht das auch so!

Bemerkung: signed brauch ich nicht, aber quasi so etwas wie eine int sequence.

Mein Lösung (hoffe damit erkennst du den Fehler in deinem Code, wenn nicht schrei ganz laut):

char * hexToByteChar(std::string hexstr, char * buf) {

    	for (size_t i = 0; i < hexstr.length(); i += 2)
        {
	     unsigned int b = 0;
	     const char arr[] = { hexstr**, hexstr[i + 1]};
	     std::string str(arr, 2);
	     std::istringstream ss(str);
	     ss >> std::hex >> b;
  	     buf[i / 2] = b;
	     printf("%x ", b);
    }
    printf("\n");
    return buf;
}

Ich finde ja selber, dass der Caller Verantwortung übernehmen soll, vor allem bei Memory freeing Geschichten geht. Denke mir aber trotzdem, es wäre praktisch, wenn die Funktion, die ich aufrufe das Allokieren von Speicher übernimmt. Wenn nicht, sollte es möglich sein der Funktion mitzuteilen, welche Größe das Feld hat, was man übergibt, damit beim Array Zugriff nicht ein undefinierten Verhalten auftritt.

stringstream hat nur so etwas wie einen Zustand? :blush:
Also, wenn man wiederholt eine Operation darauf anwendet, kommt immer das gleiche raus? :slight_smile:

Danke für deine Hilfe! Bin gespannt, was passiert, wenn ich dann damit auf den Speicher zugreife. :smile:

Stringstream scheint zumindest den Anfangszustand zu speichern. Somit startet man wieder neu, wenn man zu viel gelesen hat. Beim Lesen vom Hex-String war das Problem, dass einfach die ganze Zeile in ein Integer umgewandelt wurde.

Ich denke, es funktioniert, aber dann iwie auch nicht:

char * hexToByteChar(std::string hex, char * buf) {
	for (size_t i = 0; i < hex.length(); i += 2)
	{
		unsigned int b;
		std::stringstream ss;
		ss << std::hex << hex** << hex[i + 1];
		ss >> b;
		buf[i / 2] = b;
	}
	for (size_t i = 0; i < hex.length(); i += 2)
	{
		// that is for control...
		printf("%02x ", buf[i / 2]);
	}
	printf("\n");
	return buf;
}

DWORD findAddr(std::string dllName, char * bytes, size_t len) {
	DWORD hModule = (DWORD)GetModuleHandleA(dllName.c_str());
	bool done = false;
	for (size_t j = hModule; j < hModule + (1024 * 1024); j++)
	{
		done = true;
		for (size_t i = 0; i < len; i++)
		{
			if (bytes** != *(char*)(j + i)) {
				done = false;
				break;
			}
		}
		if (done)
			return j;
	}
	return 0;
}
		char buf[100];
		hexToByteChar("5556578bf9", buf);
		printf("%x\n", findAddr("SciLexer.dll", buf, 5));

Es werden zu viele ff’s ausgegeben. :neutral_face:

Edit: const ist ein gutes Stichwort, eigentlich können alle Parameter const sein. :slight_smile:

Es liegt wohl diesmal bei der Datentyp Konvertierung. char scheint wohl dafür nicht ideal zu sein. short funktioniert dagegen problemlos.

Doch! (So hab ich es gelernt!)

@mdickie : Was ist denn der Unterschied zwischen, stringstream, istringstream und ostringstream? Irgendwo dran muss es ja liegen, ein char kann nicht fffffff9 sein (das wären 4 Byte)…

Wenn ich so überlege… An dieser Zuweisung wird’s liegen!

Edit: Es liegt an printf… Und die Funktion ist richtig…

Der Schneemann konnte jetzt, nachdem ich die richtige Adresse herausgefunden hab, den Rest machen:

Zusammenfassung

struct s0 {
    struct s0* f0;
    struct s0* f4;
    int8_t[12] pad20;
    uint32_t f20;
    int8_t[80] pad104;
    int32_t f104;
    int32_t f108;
    int32_t f112;
    int8_t[32] pad148;
    struct s0* f148;
};

void fun_52b0c4ad(int32_t ecx, struct s0* a2);

struct s1 {
    int8_t[2] pad2;
    struct s0* f2;
};

struct s1* fun_52baee00(struct s0* ecx, struct s0* a2);

void* fun_52b83b50(struct s0* ecx);

void* fun_52b835f0();

void fun_52ae3135(struct s0* ecx, struct s0* a2, struct s0* a3, struct s0* a4, struct s0* a5, struct s0* a6, struct s0* a7, struct s0* a8, struct s0* a9, struct s0* a10, struct s0* a11, struct s0* a12, struct s0* a13, struct s0* a14, struct s0* a15, struct s0* a16, struct s0* a17, struct s0* a18, struct s0* a19, struct s0* a20);

void fun_52ae3541(struct s0* ecx) {
    struct s0* v2;
    struct s0* v3;
    struct s0* esi4;
    struct s0** esp5;
    struct s0* v6;
    struct s0* edi7;
    struct s0* edi8;
    struct s0* v9;
    struct s0* esi10;
    struct s0* eax11;
    struct s0* v12;
    struct s0* v13;
    struct s0* eax14;
    struct s0* v15;
    struct s1* eax16;
    struct s0* edx17;
    struct s0* ecx18;
    struct s0* v19;
    struct s0* v20;
    void* esp21;
    struct s0* esi22;
    struct s0* v23;
    struct s0* ebx24;
    void* eax25;
    void* esp26;
    void* ecx27;
    void* eax28;
    struct s0* ebp29;
    struct s0* eax30;
    struct s0* edx31;
    struct s0* ecx32;
    struct s0* ebp33;
    void* esp34;
    struct s0* v35;
    struct s0* v36;
    struct s0* v37;
    struct s0* v38;
    struct s0* v39;
    struct s0* v40;
    struct s0* v41;
    void* esp42;
    struct s0* v43;
    void* esp44;
    struct s0* v45;

    v2 = (struct s0*)__return_address();
    v3 = esi4;
    esp5 = (struct s0**)((int32_t)__zero_stack_offset() - 4 - 4 - 4);
    v6 = edi7;
    edi8 = ecx;
    v9 = (struct s0*)(esp5 + 20);
    fun_52b0c4ad((int32_t)edi8 + 88, v9);
    asm("fld1");
    esi10 = (struct s0*)((int32_t)edi8 + 32);
    asm("fstp dword [esp+0x40]");
    asm("fld dword [esp+0x58]");
    asm("fsub dword [esp+0x50]");
    eax11 = v12->f0;
    v13 = esi10;
    asm("fstp dword [esp+0x30]");
    asm("fld dword [esp+0x30]");
    asm("fld1");
    asm("fsubp st1, st0");
    asm("fstp dword [esp+0x4c]");
    eax11->f104(v12);
    eax14 = v12->f0;
    asm("fstp qword [esp+0x38]");
    v15 = esi10;
    eax14->f112(v12, v15);
    asm("fsubr qword [esp+0x38]");
    asm("fstp dword [esp+0x2c]");
    asm("fld dword [esp+0x2c]");
    asm("fadd qword [0x52bc94a8]");
    eax16 = fun_52baee00(v12, v15);
    edx17 = v12->f0;
    ecx18 = v12;
    v19 = esi10;
    v20 = (struct s0*)&eax16->f2;
    edx17->f108(ecx18, v19, v15);
    esp21 = (void*)(esp5 - 1 - 1 + 1 - 1 - 1 + 1 - 1 - 1 + 1 - 1 + 1 - 1 - 1 + 1);
    asm("fild dword [esp+0x2c]");
    esi22 = (struct s0*)&edi8->pad20;
    v23 = esi22;
    asm("fstp dword [esp+0x2c]");
    asm("fadd dword [esp+0x2c]");
    asm("fld1");
    asm("faddp st1, st0");
    asm("fstp dword [esp+0x4c]");
    if (esi22->f20 < 16) {
        ebx24 = esi22;
    } else {
        ebx24 = esi22->f0;
    }
    *(int8_t*)((int32_t)&v3 + 3) = 1;
    do {
        eax25 = fun_52b83b50(ecx18);
        esp26 = (void*)((int32_t)esp21 - 4 - 4 - 4 + 4 + 4 + 4);
        ecx27 = eax25;
        if (!ecx27) {
            eax28 = fun_52b835f0();
            esp26 = (void*)((int32_t)esp26 - 4 - 4 + 4 + 4);
            *(int8_t*)((int32_t)&v3 + 3) = 0;
            ecx27 = (void*)((int32_t)ebx24 + (int32_t)eax28);
        }
        if (esi22->f20 >= 16) {
            esi22 = esi22->f0;
        }
        ebp29 = edi8->f0;
        eax30 = (struct s0*)((int32_t)ebx24 - (int32_t)esi22);
        edx31 = (struct s0*)((int32_t)ecx27 - (int32_t)ebx24 + (int32_t)eax30);
        if ((int32_t)ebp29 <= (int32_t)eax30) {
            ebp29 = eax30;
        }
        if ((int32_t)ebp29 >= (int32_t)edx31) {
            ebp29 = edx31;
        }
        ecx32 = edi8->f4;
        ebp33 = (struct s0*)((int32_t)ebp29 - (int32_t)eax30);
        if ((int32_t)ecx32 <= (int32_t)eax30) {
            ecx32 = eax30;
        }
        if ((int32_t)ecx32 >= (int32_t)edx31) {
        }
        esp34 = (void*)((int32_t)esp26 - 16);
        asm("fild dword [esp+0x28]");
        v35 = edi8->f148;
        asm("fstp dword [esp+0x58]");
        fun_52ae3135(v20, v36, (int32_t)esp34 + 40, ebx24, 0, ebp33, v2, 0, v37, v38, v39, v40, v41, v19, v15, v13, v9, v6, v3, v35);
        esp42 = (void*)((int32_t)esp34 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 + 4 - 16);
        v43 = ebx24;
        fun_52ae3135(v38, v23, (int32_t)esp42 + 40, v43, ebp33, v38, 0, 1, v23, v6, v3, v35, v2, v36, (int32_t)esp34 + 40, ebx24, 0, ebp33, v2, 0);
        esp44 = (void*)((int32_t)esp42 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 + 4 - 16);
        edi8 = v6;
        ecx18 = edi8;
        v45 = v23;
        fun_52ae3135(ecx18, v23, (int32_t)esp44 + 40, ebx24, v6, v36, v45, 0, v13, ebp33, v2, 0, v37, v23, (int32_t)esp42 + 40, v43, ebp33, v38, 0, 1);
        esp21 = (void*)((int32_t)esp44 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 + 4);
        ebx24 = (struct s0*)1;
        asm("fild dword [esp+0x34]");
        asm("fstp dword [esp+0x34]");
        asm("fld dword [esp+0x34]");
        asm("fadd dword [esp+0x4c]");
        asm("fstp dword [esp+0x4c]");
        if ((int32_t)v37 <= 0) {
        }
        esi22 = v43;
    } while (*(int8_t*)((int32_t)&v45 + 3));
    goto (int32_t)esp34 + 40;
}

fun_52ae3541 ist die Funktion, die mit (0x)5556578bf9 beginnt… :slight_smile: