[ASM] Objaśnienie kodu, dezasemblacja, hex editing

0

Witam,
Nie miałem nigdy do czynienia z ASM-em, jednakże musze zmienić w nim pewną rzecz. Oczywiście jest to sprawa typu reverse engineering przy pomocy IDA, a potem ew. Hex Editora.

sub_41A280 proc near

var_20= dword ptr -20h
var_1C= dword ptr -1Ch
var_C= dword ptr -0Ch
var_4= dword ptr -4
arg_0= byte ptr  8
arg_4= dword ptr  0Ch
arg_8= dword ptr  10h

push    ebp
mov     ebp, esp
push    0FFFFFFFFh
push    offset unknown_libname_110 ; Microsoft VisualC 2-8/net runtime
mov     eax, large fs:0
push    eax
mov     large fs:0, esp
sub     esp, 14h
mov     [ebp+var_20], ecx
lea     ecx, [ebp+var_1C]
call    sub_4026C0
mov     [ebp+var_4], 0
mov     eax, [ebp+arg_8]
push    eax
mov     ecx, [ebp+arg_4]
push    ecx
mov     edx, dword ptr [ebp+arg_0]
push    edx             ; char
push    offset aInsertIntoPkbu ; "INSERT INTO PKBulletin VALUES ( '%s', '"...
lea     eax, [ebp+var_1C]
push    eax             ; int
call    sub_402730
add     esp, 14h
mov     [ebp+var_4], 0FFFFFFFFh
lea     ecx, [ebp+var_1C]
call    sub_4026F0
mov     ecx, [ebp+var_C]
mov     large fs:0, ecx
mov     esp, ebp
pop     ebp
retn    0Ch
sub_41A280 endp

Jest to kod, a w zasadzie chyba funkcja odpowiedzialna za dodawanie pewnych danych do bazy MSSQL.
Nie rozumiem o co tu biega, aczkolwiek mam pare pytań.

  1. Gdzie są przypisane parametry jakie funkcja otrzyma podczas wywołania?
sub_41A280 proc near

push offset aInsertIntoPkbu
Ten kod jak mi sie wydaje wywołuje zapytanie do bazy (u mnie MSSQL).
Jednak zapytanie ma postać: 'INSERT INTO PKBulletin VALUES ( ',27h,'%s',27h,', ',27h,'%s',27h,', ',27h,'%s',27h,')'
Tabela ma 3 pola, wiec jak mi sie wydaje %s to gdzie zmienna string zostanie wstawiona, a 27h to jakies przerwanie od wypisania tekstu?

  1. Gdzie kod:
push    offset aInsertIntoPkbu 

Otrzymuje zmienne do przekazania do tego zapytania?

Wybaczcie jeśli coś nazmyślałem, pierwszy raz na oczy widze takie ślaczki.

0

O argumentach świadczą dwie rzeczy:

arg_0= byte ptr  8
arg_4= dword ptr  0Ch
arg_8= dword ptr  10h

oraz:

mov     [ebp+var_20], ecx
;; ...
retn    0Ch

Wedle listy argumentów funkcja w stdcall korygująca stos o 12 bajtów podczas powrotu, 4 bajty na argument - 3 argumenty. Ale, dlatego wspomniałem o ecx bo to nie stdcall a thiscall, ta funkcja jest metodą klasy, this zaś jest przekazywany w ecx, faktycznych argumentów metody faktycznie jest 3.

O tym co dokładnie robi funkcja to trochę trudno powiedzieć. Wspomniany push to wrzucenie adresu stringa na stos, przekazanie go jako argument funkcji. Nie znam API MySQL, trudno powiedzieć co tam dokładnie odchodzi. Uwzględniając thiscall i to, że var_1C nie jest inaczej inicjalizowany niż przez wywołanie metody (nazwijmy tą zmienną 'zuo') to możemy przyjąć, że to konstruktor. Ostatnie wywołanie też jest wywołaniem metody, jego wyniki są zaś ignorowane, wygląda na destruktor. Jeżeli nie jest to destruktor to funkcja zwraca wynik tej metody, inaczej to void. Skoro kod obiektowy to zuo jest zapewne przyjmowane przez referencję zamiast jawnie przez wskaźnik. Więc albo:

void CJakiasKlasa::sub_41A280(char *arg_0, char *arg_4, char *arg_8) {
    CJakiesZuo zuo; /* wolany konstruktor domyslny sub_4026C0 */

    sub_402730(zuo, "INSERT INTO PKBulletin VALUES ('%s', '%s', '%s')", arg_0, arg_4, arg_8);
    /* niejawnie wołany sub_4026F0, destruktor zuo */
}

albo:

JakiesCos CJakasKlasa::sub_41A280(char *arg_0, char *arg_4, char *arg_8) {
    CJakasKlasa zuo; /* wolany konstruktor domyslny sub_4026C0 */

    sub_402730(zuo, "INSERT INTO PKBulletin VALUES ('%s', '%s', '%s')", arg_0, arg_4, arg_8);
    return zuo.jakasMetoda();
}

Ogólnie całość objęta jest obsługą wyjątków... Stawiam na to pierwsze. W praktyce to wszystko zgadywanie, trudno powiedzieć co tutaj odchodzi, za mało kodu, wypadałoby przejrzeć dokumentację MySQL++ lub\i wygenerować sygnatury z tej biblioteki i do IDy wrzucić. Równie dobrze może po prostu składać zapytanie z trzeba stringami podanymi jako argumenty co także je wykonywać. Jeżeli miałem rację - wykonuje.

Popraw temat na sensowniejszy.

0

Piąte przez dziesiąte wpadło mi do głowy, troche mi to objaśniło. Dzięki
Wiem, już czego chce w każdym razie.

Teraz tylko mam pare pytań w związku z dezasemblacją i hex editingiem.
Do wstępnej analizy kodu używam IDA Pro, do edycji zdeasemblowanego kodu (zamiany instrukcji ASM-a i wygnerowanie nowego HEXa) używam OllyDBG.
Natomiast do samego edytowania HEXow uzywam XVI32.

Znalazłem co chce zmienić w Idzie, przeszedłem do OllyDBG zamieniłem instrukcje na inną i zauważyłem także zmiany w kodzie HEX. Jednak to tylko podgląd, a nie zapis do pliku. Zapisałem adres linijki i przeszedłem do XVI32.
Tam nie ma takiego adresu, adresy koncza sie na E6FF9. W Ollym koncza sie na 004B3FF0.
Próbowałem szukać po HEX-ie i Stringu, jednak nie znalazłem.
Co robie żle i dlaczego tak sie dzieje?
Czy można powyższe czynności wykonać w Idzie, czy OllyDBG?

0

Po pierwsze gratuluję poprawnego tłumaczenia terminu, faktycznie poprawna forma to dezasemblacja, praktycznie jednak się z nią nie spotykam.

Kilka lat temu był wątek o tłumaczeniu plug-ina do Winampa, tam się dokładnie o kilku rzeczach napisałem, teraz omówię tylko ogólnie co i jak.

Znalazłem co chce zmienić w Idzie, przeszedłem do OllyDBG zamieniłem instrukcje na inną i zauważyłem także zmiany w kodzie HEX. Jednak to tylko podgląd, a nie zapis do pliku.

Najprostsza metoda, pozwalająca na uniknięcie szczegółów technicznych. Wprowadź zmiany pod Olly\ImmDbg (Imm to pochodna Olka, którą preferuję), kliknij prawym w oknie kodu i daj Copy to executable => All modifications. Debugger sam obliczy prawidłowe adresy w binarce i zapisze zmiany na bazie modyfikacji widocznych w oknie Patches.

Tam nie ma takiego adresu, adresy koncza sie na E6FF9. W Ollym koncza sie na 004B3FF0.
Próbowałem szukać po HEX-ie i Stringu, jednak nie znalazłem.
Co robie żle i dlaczego tak sie dzieje?
Czy można powyższe czynności wykonać w Idzie, czy OllyDBG?

OK, zacznijmy od tego, że każdy program ma adres bazowy - IMAGE BASE, pod który moduł jest ładowany, jest on zapisany w nagłówku pliku. Następne o czym musisz wiedzieć to to, że moduł poza nagłówkiem składa się z sekcji, bloków danych o różnych atrybutach - kod, dane zainicjalizowane, niezainicjalizowane, importy, zasoby itd. Każda sekcja ma adres fizyczny - offset w pliku (u Ciebie E6FF9) i RVA, czyli wirtualny adres względny - adres w pamięci względem początku modułu. Suma RVA i IMAGE BASE to VA, faktyczny adres w pamięci (tak jak podałeś - 004B3FF0). Adres w pliku to offset sekcji + przesunięcie względem jej początku, w pamięci zaś VA + przesunięcie.

Offset aktualnej instrukcji podaje Ci IDA na belce statusu, w pierwszym panelu, ma on hint Current offset in the input file. Olly zaś pozwala podejrzeć adresy instrukcji poprzez menu kontekstowe i View => Executable File. Wedle tego można grzebać hexedytorem.

Polecam 'zainwestować' w jakiś edytor PE, np. LordPE albo StudPE, przyda się do wprowadzania zmian w strukturze + ew. szybkiego przeliczania adresów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1