Comment afficher les membres KUSER_SHARED_DATA en code C décompilé?

Oct 23 2020

Voici un exemple de code C qui imprime la version de Windows directement à partir de l'adresse de KUSER_SHARED_DATA . Testé sous Windows 10 uniquement. L'adresse de la mémoire brute diffère dans la version de Windows, mais ce n'est pas le point.

#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)
    );
}

Voici le code décompilé:

Dans 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;
}

Dans IDA Pro + Hex-Rays:

int __fastcall main()
{
    wprintf(L"Version: %lu.%lu.%lu\n",
        MEMORY[0x7FFE026C],
        MEMORY[0x7FFE0270],
        MEMORY[0x7FFE0260]);
  return 0;
}

Ma question: en code décompilé, est-il possible d'afficher l'adresse mémoire en tant que membre de KUSER_SHARED_DATA? Par exemple, je veux montrer MEMORY[0x7FFE0260]comme SharedData.NtBuildNumberou quelque chose de similaire.

Réponses

3 RolfRolles Oct 23 2020 at 11:58

Pour IDA / Hex-Rays:

  1. Dans la fenêtre Bibliothèques de types View->Open subviews->Type librarieschargés ( ), chargez ntddk_win10(ou quelle que soit la version de Windows souhaitée, revenez à Windows XP et Windows Server 2003).

  1. Dans la fenêtre Structures ( View->Open subviews->Structures), importez KUSER_SHARED_DATA. Vous pouvez simplement écrire le nom du type dans la boîte de dialogue et appuyer sur OK, comme dans l'image suivante:

  1. Sous Edit->Segments->Create segment, créez un nouveau segment avec cette plage de mémoire, comme dans l'image suivante.

  1. Au début du nouveau segment, utilisez Edit->Struct varet sélectionnez KUSER_SHARED_DATA.

C'est ça. Maintenant, la liste de démontage ressemble à ceci:

Et la décompilation ressemble à ceci:

2 blabb Oct 24 2020 at 04:06

Ghidra

addr = toAddr(0x7ffe0000)
currentProgram.memory.createUninitializedBlock("KUSER_SHARED_PAGE",addr,0x1000,0)
createData(addr,getDataTypes("KUSER_SHARED_DATA")[0])

résultat

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éthode 1)

Utilisez VirtualQuery pour obtenir la taille
ci-dessous est un python python comparez le résultat à (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éthode 2)

utilisez windbg! vprot pour obtenir la même chose

:\>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éthode 3)

utilisez l'adresse windbg! pour obtenir des détails plus détaillés du même espace d'adressage

:\>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: