unc4nny Posted April 15, 2020 at 09:03 PM Share Posted April 15, 2020 at 09:03 PM Oi. No livro Practical Reverse Engineering, o autor mostra um trecho de codigo asm. Numa parte do codigo, tem a seguinte sequencia de instrucoes: Pesquisando eu vi que o sidt eh uma instrucao que carrega o Interrupt Descriptor Table no endereco especificado, e ele esta comparando para ver se o base address do IDT esta no range especificado no codigo (8003f400h-80047400h). Isso eh uma tecnica para ver se o programa esta rodando em maquina virtual. A duvida vem aqui: Na hora que o cara vai explicar (decompilar o codigo) ele faz da seguinte maneira: typedef struct _IDTR { DWORD base; SHORT limit; } IDTR, *PIDTR; BOOL __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ IDTR idtr; __sidt(&idtr); if (idtr.base > 0x08003f40 && idtr.base < 0x80047400) return FALSE; } Minha duvida eh justamente no __sidt(&idtr); Fui tentar reproduzir um codigo similar aqui na minha VM, mas da erro de compilacao. Estou usando o Dev-C++ Segue o codigo: #include <windows.h> #include <stdio.h> typedef struct _IDTR{ DWORD base; SHORT limit; } IDTR, *PIDTR; int main(){ IDTR idtr; __sidt(&idtr); printf( "Base: %d\r\nLimit: %d\r\n", idtr.base, idtr.limit ); return 0; } O erro sendo gerado eh: undefined reference to __sidt. To lendo a documentacao do __asm no site da microsoft mas ate agora nao achei nada que me ajudou. Alguem pode me dar uma luz? Eu quero escrever o Interrupt Descriptor Table em alguma variavel que eu consiga ler, ou ate mesmo ler o IDTR em si. Obrigado desde ja! EDIT: Eu esqueci de escrever o #include <intrin.h> que supostamente eh o headerfile onde __sidt esta definido, mas esta incluso! Link to comment Share on other sites More sharing options...
Felipe.Silva Posted April 16, 2020 at 02:50 AM Share Posted April 16, 2020 at 02:50 AM Colega, pelo que pesquisei aqui isto é uma instrução intrísseca do compilador do Visual Studio (Microsoft). Tem muita coisa em C que não é padronização da linguagem mas sim de alguma implementação específica, esta é uma delas. https://docs.microsoft.com/pt-br/cpp/intrinsics/sidt?view=vs-2019 Se você usa o GCC, e suponho que sim, você pode usar Inline Assembly para isso. (outros compiladores também suportam Inline Assembly, mas com sintaxe diferente) Vou deixar um exemplo: #include <stdio.h> #include <inttypes.h> typedef struct idtr_s { void *base; uint16_t limit; } idtr_t; inline void sidt(idtr_t *idtr) { __asm__ ( "sidt %0" : "=m" (idtr) ); } int main(void) { idtr_t idt; sidt(&idt); printf("%p, %" PRIu16 "\n", idt.base, idt.limit); return 0; } Detalhe que o uso de uma inline function demanda que você ligue a otimização de código na hora de compilar. Tu pode por exemplo fazer assim: $ gcc -O2 tst.c -o tst Ah, uma pequena nota, sem querer atropelhar o autor. Mas o uso de DWORD para 'base' não está tecnicamente correto. Ele está assumindo que o tamanho do dado será necessariamente 4 bytes, mas isso só é verdade se o programa não estiver rodando em modo de 64-bit. Por isso usei um ponteiro void no lugar. EDIT: A instrução SIDT não carrega a IDT, carrega o IDTR que é um registrador que armazena estas informações sobre a IDT. "base" no caso é o endereço inicial de onde a IDT está. Link to comment Share on other sites More sharing options...
unc4nny Posted April 16, 2020 at 11:48 AM Author Share Posted April 16, 2020 at 11:48 AM Cara, muito obrigado mil vezes!!! Depois que eu enviei a pergunta eu achei esse inline assembly e nao tava conseguindo fazer funcionar nem a pau. 8 hours ago, Felipe.Silva said: A instrução SIDT não carrega a IDT, carrega o IDTR que é um registrador que armazena estas informações sobre a IDT. "base" no caso é o endereço inicial de onde a IDT está. Ops, eh vdd, my bad. Cara mto obrigado!! Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.