2016-06-20 2 views
0

La question est assez simple, ce que j'essaie de faire est de restaurer les fonctions déviées de mon processus.Récupération des fonctions de bibliothèque détournées

Quand je dis détour, je veux dire l'instruction habituelle jmp vers un lieu inconnu. Par exemple, lorsque l'exportation ntdll.dll NtOpenProcess() n'est pas détournée, les 5 premiers octets de l'instruction de la fonction correspondent aux lignes mov eax, *.

(Le * décalage en fonction de la version du système d'exploitation.)

Quand il est déviée, que mov eax, * se transforme en un jmp.

Ce que je suis en train de faire est de restaurer leurs octets à ce qu'ils étaient à l'origine avant toute modification de la mémoire.

Mon idée était d'essayer de lire les informations dont j'avais besoin à partir du disque, pas de la mémoire, mais je ne sais pas comment le faire car je ne suis qu'un débutant.

Toute aide ou explication est grandement la bienvenue, si je n'ai pas expliqué mon problème correctement s'il vous plaît dites-moi!

Répondre

0

J'ai fini par comprendre.

Exemple sur NtOpenProcess. Au lieu de restaurer les octets, j'ai décidé de sauter par-dessus.

Nous devons d'abord définir la base de ntdll.

/* locate ntdll */ 
#define NTDLL _GetModuleHandleA("ntdll.dll") 

Une fois que nous l'avons fait, nous sommes prêts à partir. GetOffsetFromRva calculera le décalage du fichier en fonction de l'adresse et de l'en-tête du module qui lui est passé. Nous appelons cela pour obtenir le décalage de fichier dont nous avons besoin pour trouver les octets originaux de la fonction. En utilisant la fonction qui nous permet d'obtenir le décalage de fichier, nous pouvons maintenant lire les octets d'exportation d'origine.

size_t ReadExportFunctionBytes(HMODULE hmModule, char* szExportName, BYTE* lpBuffer, size_t t_Count) 
{ 
    /* get the offset */ 
    DWORD dwFileOffset = GetExportPhysicalAddress(hmModule, szExportName); 
    if (!dwFileOffset) 
    { 
     return 0; 
    } 

    /* get the path of the targetted module */ 
    char szModuleFilePath[MAX_PATH]; 
    GetModuleFileNameA(hmModule, szModuleFilePath, MAX_PATH); 
    if (strnull(szModuleFilePath)) 
    { 
     return 0; 
    } 

    /* try to open the file off the disk */ 
    FILE *fModule = fopen(szModuleFilePath, "rb"); 
    if (!fModule) 
    { 
     /* we couldn't open the file */ 
     return 0; 
    } 

    /* go to the offset and read it */ 
    fseek(fModule, dwFileOffset, SEEK_SET); 
    size_t t_Read = 0; 

    if ((t_Read = fread(lpBuffer, t_Count, 1, fModule)) == 0) 
    { 
     /* we didn't read anything */ 
     return 0; 
    } 

    /* close file and return */ 
    fclose(fModule); 

    return t_Read; 
} 

Et nous pouvons récupérer l'index syscall de l'instruction mov initialement placé dans les 5 premiers octets de l'exportation sur x86.

DWORD GetSyscallIndex(char* szFunctionName) 
{ 
    BYTE buffer[5]; 
    ReadExportFunctionBytes(NTDLL, szFunctionName, buffer, 5); 
    if (!buffer) 
    { 
     return 0; 
    } 

    return BytesToDword(buffer + 1); 
} 

Obtenez l'adresse NtOpenProcess et ajoutez 5 au trampoline par-dessus.

DWORD _ptrNtOpenProcess = (DWORD) GetProcAddress(NTDLL, "NtOpenProcess") + 5; 
DWORD _oNtOpenProcess = GetSyscallIndex("NtOpenProcess"); 

récupéré/reconstruit NtOpenProcess.

__declspec(naked) NTSTATUS NTAPI _NtOpenProcess 
(
    _Out_ PHANDLE   ProcessHandle, 
    _In_  ACCESS_MASK  DesiredAccess, 
    _In_  POBJECT_ATTRIBUTES ObjectAttributes, 
    _In_opt_ PCLIENT_ID   ClientId 
) { 
    __asm 
    { 
     mov eax, [_oNtOpenProcess] 
     jmp dword ptr ds : [_ptrNtOpenProcess] 
    } 
} 

Appelons-le.

int main() 
{ 
    printf("NtOpenProcess %x index: %x\n", _ptrNtOpenProcess, _oNtOpenProcess); 

    uint32_t pId = 0; 
    do 
    { 
     pId = GetProcessByName("notepad.exe"); 
     Sleep(200); 

    } while (pId == 0); 

    OBJECT_ATTRIBUTES oa; 
    CLIENT_ID cid; 
    cid.UniqueProcess = (HANDLE)pId; 
    cid.UniqueThread = 0; 
    InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL); 

    HANDLE hProcess; 
    NTSTATUS ntStat; 

    ntStat = _NtOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &oa, &cid); 

    if (!NT_SUCCESS(ntStat)) 
    { 
     printf("Couldn't open the process. NTSTATUS: %d", ntStat); 
     return 0; 
    } 

    printf("Successfully opened the process."); 

    /* clean up. */ 
    NtClose(hProcess); 

    getchar(); 
    return 0; 
}