ABUSO DE GADGET ICALL PARA COMUNICAÇÃO
Então eu estava rolando pelo IDA e encontrei isto
image
Após uma inspeção mais aprofundada, podemos ver que ele chama uma função chamada _guard_dispatch_icall_ptr. O icall basicamente é um jmp para rax, então se você pensar um pouco, podemos modificar toda essa função para, em vez disso, chamar nosso handler usando shellcode.
Nosso Shellcode
Vamos criar um shellcode que define rax como um ponteiro para nossa função handler. Assim, quando a função for chamada, ela executará nosso shellcode e chamará nosso handler. Queremos garantir que, ao criar nosso shellcode, ele tenha exatamente o mesmo tamanho em bytes que o código que estamos modificando. Então aqui está um exemplo do shellcode que usei em asm; você precisará convertê-lo para bytes.
sub rsp,0x38
movabs rax,0xdeadbeef #placeholder for handler
movabs r10,0xab39cfee
inc rax
dec rax
call QWORD PTR [rip+0x720d4] # 0x720f8
jmp 0x29
Nosso código
Em cpp, precisamos apenas obter o endereço da função e então mapear nosso shellcode nela, mas aqui é onde fica complicado: se fizermos isso simplesmente como está, corromperemos a pilha e teremos bluescreen de vez em quando. Para evitar isso, precisaremos reparar a pilha. Então, em vez de retornar dentro do nosso handler, devemos executar as mesmas operações que as funções estariam fazendo se não a tivéssemos modificado. Vou deixar isso para o leitor fazer por conta própria, porque não quero dar de mão beijada um método incrível de evasão de anticheats, mas lembre-se de olhar o asm original da função e ver o que estamos modificando. NOTA LATERAL: Se você corrigir a corrupção da pilha e fizer o que a função pretendia fazer dentro do seu handler, vai parecer que nada foi modificado! :)
//getting address to function
FunctionAddress = module + 0xD70C;
BYTE shellcode[] = { 0x48, 0x83, 0xEC, 0x38, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x49, 0xBA, 0xEE, 0xCF, 0x39, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x48, 0xFF, 0xC0, 0x48, 0xFF, 0xC8, 0xFF, 0x15, 0xD4, 0x20, 0x07, 0x00, 0xE9, 0x00, 0x00, 0x00, 0x00 };
memcpy(&shellcode[6], &hkfunction, 8);
DisableWriteProtection();
memcpy((PVOID)FunctionAddress, &shellcode, sizeof(shellcode));
EnableWriteProtection();
Conclusão
Espero que você tenha tirado algo deste rápido write-up; apenas saiba que você também pode encontrar outros gadgets que farão muito mais, e quanto mais complexo, melhor.