2016-05-18 9 views
1

Ich versuche, PEB-Adresse des aktuellen Prozesses mit Assembler zu erhalten.Wie bekomme ich die Adresse des Process Environment Blocks (PEB) mit Assembler (x64 OS)?

die CPP-Datei:

#include <iostream> 
//#include <windows.h> 

extern "C" int* __ptr64 Get_Ldr_Addr(); 

int main(int argc, char **argv) 
{ 
    std::cout << "asm  " << Get_Ldr_Addr() << "\n"; 
    //std::cout <<"peb  "<< GetModuleHandle(0) << "\n"; 

    return 0; 
} 

die asm-Datei:

.code 

Get_Ldr_Addr proc 
    push rax 
    mov rax, GS:[30h] 
    mov rax, [rax + 60h] 
    pop rax 
    ret 
Get_Ldr_Addr endp 

end 

Aber ich verschiedene Adressen aus dem GetModuleHandle (0) und der Get_Ldr_Addr()!

Was ist das Problem? soll nicht dasselbe sein?

Q: Wenn die Funktion extern ist, wird es die PEB des Prozesses, der es aufgerufen hat oder der Funktion dll (es wird angenommen, dass eine DLL sein)?

Tnx

+1

Wo setzen Sie Ihren Rückgabewert ein? Anscheinend laden Sie es in RAX, aber dann wird es vom Pop überschrieben. Überprüfen Sie, wie Sie den Wert in Ihrem ABI zurückgeben sollen. –

+0

Ich löschte den Push/Pop. und dies ist der Weg, den Wert gemäß einer Anweisung zurückzugeben. https://deverorel.wordpress.com/2015/01/19/compiling-64-bit-assembler-code-in-visual-studio-2014/ –

+0

Eine andere Möglichkeit, einen Zeiger auf den 'PEB' eines Prozesses zu bekommen, ohne auf Assembly zurückgreifen zu müssen, ist die Verwendung von ['NtQueryInformationProcess()'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280.aspx): "* Wenn die' ProcessInformationClass' Parameter ist 'ProcessBasicInformation', der Puffer, auf den der Parameter 'ProcessInformation' zeigt, sollte groß genug sein, um eine einzige' PROCESS_BASIC_INFORMATION'-Struktur zu enthalten ... [deren] 'PebBaseAddress'-Member auf eine' PEB'-Struktur zeigt. * " –

Antwort

2

Nur zwei Kommentare.

Keine Notwendigkeit zu drücken/pop rax, weil es ein Kratzer oder volatile Register unter Windows ist, siehe caller/callee saved registers. Insbesondere wird rax den Rückgabewert für Ihre Funktion enthalten.

Oft hilft es, den Maschinencode zu durchlaufen, wenn Sie GetModuleHandle() aufrufen und vergleichen Sie es mit Ihrem eigenen Assembly-Code. Sie werden wahrscheinlich auf etwas wie this implementation stoßen.

+0

Ich werde es jetzt überprüfen. tnx –

+0

Ich versuche das gleiche zu tun, aber für x64. aber VS erlaubt/unterstützt x64 Assembler nicht, also lege ich es in eine andere Datei (.asm). vielleicht sind die PEB-Adresse und die Handler-Adresse anders? –

+0

Das Format der Struktur bei gs/fs unterscheidet sich für x86 und x64 (teilweise eine Widerspiegelung der Tatsache, dass Zeiger unterschiedliche Größen haben). –

1

Get_Ldr_Addr hat das Ergebnis nicht gespeichert.

Sie sollten nicht rax von Push- und Pop-Schutz, weil rax Der Rückgabewert ist

2

Wenn Sie nichts dagegen C. Arbeitet in Microsoft Visual Studio 2015 die „__readgsqword()“ Verwendet intrinsische.

#include <winnt.h> 
#include <winternl.h> 

// Thread Environment Block (TEB) 
#if defined(_M_X64) // x64 
PTEB tebPtr = reinterpret_cast<PTEB>(__readgsqword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self))); 
#else // x86 
PTEB tebPtr = reinterpret_cast<PTEB>(__readfsdword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self))); 
#endif 

// Process Environment Block (PEB) 
PPEB pebPtr = tebPtr->ProcessEnvironmentBlock;