Como mostrar membros KUSER_SHARED_DATA em código C descompilado?
Aqui está um exemplo de código C que imprime a versão do Windows diretamente do endereço de KUSER_SHARED_DATA . Testado apenas no Windows 10. O endereço da memória bruta difere na versão do Windows, mas esse não é o ponto.
#include <stdio.h>
int main(void)
{
wprintf(
L"Version: %lu.%lu.%lu\n",
*(unsigned int *)(0x7FFE0000 + 0x026C),
*(unsigned int *)(0x7FFE0000 + 0x0270),
*(unsigned int *)(0x7FFE0000 + 0x0260)
);
}
Aqui está o código descompilado:
Em GHIDRA:
int main(int _Argc,char **_Argv,char **_Env)
{
wprintf(L"Version: %lu.%lu.%lu\n",
(ulonglong)_DAT_7ffe026c,
(ulonglong)_DAT_7ffe0270,
(ulonglong)_DAT_7ffe0260);
return 0;
}
Em IDA Pro + Hex-Rays:
int __fastcall main()
{
wprintf(L"Version: %lu.%lu.%lu\n",
MEMORY[0x7FFE026C],
MEMORY[0x7FFE0270],
MEMORY[0x7FFE0260]);
return 0;
}
Minha pergunta: Em código descompilado, é possível mostrar o endereço de memória como o membro de KUSER_SHARED_DATA? Por exemplo, quero mostrar MEMORY[0x7FFE0260]como SharedData.NtBuildNumberou algo semelhante a ele.
Respostas
Para IDA / Hex-Rays:
- Na janela Bibliotecas de Tipo Carregado (
View->Open subviews->Type libraries), carreguentddk_win10(ou qualquer versão do Windows que você deseja, de volta ao Windows XP e Windows Server 2003).
- Na janela Estruturas (
View->Open subviews->Structures), importeKUSER_SHARED_DATA. Você pode simplesmente escrever o nome do tipo na caixa de diálogo e pressionar OK, como na imagem a seguir:
- Abaixo
Edit->Segments->Create segment, crie um novo segmento com esse intervalo de memória, como na imagem a seguir.
- No início do novo segmento, use
Edit->Struct vare selecioneKUSER_SHARED_DATA.
É isso. Agora, a lista de desmontagem se parece com isto:
E a descompilação é assim:
ghidra
addr = toAddr(0x7ffe0000)
currentProgram.memory.createUninitializedBlock("KUSER_SHARED_PAGE",addr,0x1000,0)
createData(addr,getDataTypes("KUSER_SHARED_DATA")[0])
resultado
undefined8 main(void)
{
wprintf((__crt_locale_pointers *)L"Version: %lu.%lu.%lu\n",
(ulonglong)KUSER_SHARED_DATA_7ffe0000.NtMajorVersion,
(ulonglong)KUSER_SHARED_DATA_7ffe0000.NtMinorVersion,
(ulonglong)KUSER_SHARED_DATA_7ffe0000.NtBuildNumber);
return 0;
}
Método 1)
Use VirtualQuery para obter o tamanho
mostrado abaixo é um python poc compare o resultado com (MEMORY_BASIC_INFO *) foo.RegionSize
:\>cat vq.py
from ctypes import *
meminfo =(c_ulong * 0x8)()
windll.kernel32.VirtualQuery(0x7ffe0000,byref(meminfo),sizeof(meminfo))
for i in meminfo:
print (hex(i))
:\>python vq.py
0x7ffe0000
0x7ffe0000
0x2
0x1000
0x1000
0x2
0x20000
0x0
Método 2)
use windbg! vprot para obter o mesmo
:\>cdb -c "!vprot 7ffe0000;q" cdb | awk "/Reading/,/quit/"
0:000> cdb: Reading initial command '!vprot 7ffe0000;q'
BaseAddress: 7ffe0000
AllocationBase: 7ffe0000
AllocationProtect: 00000002 PAGE_READONLY
RegionSize: 00001000
State: 00001000 MEM_COMMIT
Protect: 00000002 PAGE_READONLY
Type: 00020000 MEM_PRIVATE
quit:
Método 3)
use o endereço windbg! para obter detalhes mais detalhados do mesmo espaço de endereço
:\>cdb -c "!address 7ffe0000;q" cdb | awk "/Usage:/,/quit/"
Usage: Other
Base Address: 7ffe0000
End Address: 7ffe1000
Region Size: 00001000 ( 4.000 kB)
State: 00001000 MEM_COMMIT
Protect: 00000002 PAGE_READONLY
Type: 00020000 MEM_PRIVATE
Allocation Base: 7ffe0000
Allocation Protect: 00000002 PAGE_READONLY
Additional info: User Shared Data
Content source: 1 (target), length: 1000
quit: