Tiap melakukan load image, windows loader akan memulainya dengan membuat section dan mengakhiri dengan menyimpan informasi loaded image pada PEB (Process Environtment Block).
Process pembuatan section kita bisa liat pada doxygen reactos (for apicall) yang adalah sebagai berikut :
LdrpLoadDll
http://doxygen.reactos.org/dd/d83/nt...37d755afc40387
LdrpLoadDll akan memanggil LdrpMapDll
http://doxygen.reactos.org/dd/d83/nt...c676b0ddc5272e
LdrpMapDll akan memanggil LdrpCreateDllSection
http://doxygen.reactos.org/d8/d55/ld...ce3a541d4af034
LdrpCreateDllSection akan memanggil NtCreateSection dan seterusnya
http://doxygen.reactos.org/dd/d83/nt...37d755afc40387
LdrpLoadDll akan memanggil LdrpMapDll
http://doxygen.reactos.org/dd/d83/nt...c676b0ddc5272e
LdrpMapDll akan memanggil LdrpCreateDllSection
http://doxygen.reactos.org/d8/d55/ld...ce3a541d4af034
LdrpCreateDllSection akan memanggil NtCreateSection dan seterusnya
Pada api NtCreateSection terdapat parameter "FileHandle" yang mana disimpan sebagai informasi file dari section. informasi ini sangat berguna untuk mengetahui file path dari section saat melakukan query memory (NtQueryVirtualMemory dengan parameter MemorySectionName). Pada PEB juga disimpan mengenai image filename yang terletak pada ldr data.
Berdasarkan informasi diatas maka saya mencoba melakukan comparasi filaname yang terletak pada PEB-LDR dan filename yang terletak pada section information. Hasilnya ternyata pada beberapa emulator (tested with kaspersky) nilai kedua filename ini berbeda, alasannya karena emulator kaspersky hanya mengemulasikan PEB tidak untuk section object .
Code:
program Project1; uses Windows, jwaNative, NcxNtTeb; function ExtractFileName(FullName: String): String; var i, n: integer; begin result := ''; n := Length(FullName); Result := FullName; for i := n downto 1 do if FullName[i] = '\' then break; if i > 1 then Result := Copy(FullName, i+1, n-i); end; function NtSuccess (Stat: LongInt): Boolean; begin Result := Stat >= 0; end; Function GetModuleFileNameByAddres(ph:THandle; Address : DWord):String; var mSize,back: dword; mPtr: pointer; St: LongInt; begin result := ''; mSize := 512; mPtr := AllocMem(mSize); St := NtQueryVirtualMemory(ph, Pointer(Address), MemorySectionName, mPtr,mSize,@back); if NtSuccess(st) then result := PMEMORY_SECTION_NAME(mPtr).SectionFileName.Buffer; FreeMem(mPtr,mSize); end; function GetPEB(): Pointer; asm mov eax, large fs:30h retn end; Function CheckEmulator:Boolean; var pb: PPeb32; ldrdata: PPebLdrData32; ldrEntry: PLdrDataTableEntry32; name1, name2: String; begin //get peb pb := GetPEB; //get ldr ldrdata := pb^.Ldr; //get first ldr entry ldrEntry := ldrdata^.InLoadOrderModuleList.Flink; //get section filename name1 := ExtractFileName(GetModuleFileNameByAddres(thandle(-1), DWORD(ldrEntry^.DllBase))); //get PEB Image filename name2 := ExtractFileName(PWideChar(ldrEntry.FullDllName.Buffer)); //Compare result := name1=name2; end; begin if not CheckEmulator then messagebox(0, nil, nil, mb_ok); end.
Scanyou result test
http://scan4you.net/result.php?id=c3408_11egap
http://scan4you.net/result.php?id=dc46a_11dtd3
terakhir saya tidak bertanggung jawab atas penggunaan kode diatas karena tulisan ini saya buat hanya sebagai dokumentasi hasil research tentang bagaimana mendeteksi emulator. Semoga kedepannya av developer dapat lebih menyempurnakan emulatornya..
thanks to jasakom
No comments:
Post a Comment