0

学術研究のためにメモリから DLL の内容を読み込もうとしています。具体的には、特定の命令を変更してプログラミング エラーをシミュレートし、システムを強制的に停止させることを目的とした NTDSA.DLL ライブラリ。その後、失敗は記録され、将来の失敗を予測する機械学習アルゴリズムをトレーニングします (これは、ここで見られる以前に公開された研究を一般化する試みです)。

here で概説されているプロセスを通じて、lsass.exe プロセス (ターゲット DLL をロードする) の仮想メモリ内のベース アドレスと思われるものを取得しています。次に、割り当てられたバッファーと、'PROCESS_ALL_ACCESS' セットで OpenProcess を呼び出すことによって取得された lsass へのハンドルを使用して、ReadProcessMemory を呼び出しています。ReadProcessMemory はエラー コード 299 で 80% の時間 (部分的な読み取り) を返し、読み取りバイトはゼロです。アクセスしようとしている領域は、呼び出しが行われたときに使用されていると思います。幸いなことに、要求しているバイト数が返されることがあります。残念ながら、返されるデータは、System32 ディレクトリの静的 DLL と比較すると、ディスク上のデータと一致しません。

問題は、ReadProcessMemory が指定したアドレスで何かおかしなことをしているのか、それとも仮想アドレスが間違っているのかということです。その DLL がメモリにロードされる場所を特定する別の方法はありますか? 何かご意見は?どんな助けや提案も大歓迎です。

コードの追加:

// FaultInjection.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <windows.h>
#include <psapi.h>

#include <string>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <io.h>
#include <tchar.h>

using namespace std;

int _tmain(int argc, _TCHAR* argv[]) {

    // Declarations
    int pid = 0;
    __int64* start_addr;
    DWORD size_of_ntdsa;
    DWORD aProcesses[1024], cbNeeded, cProcesses;
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    HMODULE hmods[1024];
    unsigned int i;

    // Get All pids
    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)){
        cout << "Failed to get all PIDs: " << GetLastError() << endl;
        return -1;
    }

    // Find pid for lsass.exe
    cProcesses = cbNeeded / sizeof(DWORD);
    for (i = 0; i < cProcesses; i++) {
        if (aProcesses[i] != 0) {
            HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
            if (hProc != NULL) {
                HMODULE hMod;
                DWORD cbNeededMod;
                if (EnumProcessModules(hProc, &hMod, sizeof(hMod), &cbNeededMod)) {
                    GetModuleBaseName(hProc, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
                }

                if (wstring(szProcessName).find(L"lsass.exe") != string::npos) {
                    pid = aProcesses[i];
                }
                CloseHandle(hProc);
            }
        }
    }

    cout << "lsass pid: " << pid << endl;

    HANDLE h_lsass = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!h_lsass) {
        cout << "Failed to open process (are you root?): " << GetLastError() << endl;
        return -1;
    }

    // Get Process Image File Name
    char filename[MAX_PATH];
    if (GetProcessImageFileName(h_lsass, (LPTSTR)&filename, MAX_PATH) == 0) {
        cout << "Failed to get image file name: " << GetLastError() << endl;
        CloseHandle(h_lsass);
        return -1;
    }

    // Enumerate modules within process
    if (EnumProcessModules(h_lsass, hmods, sizeof(hmods), &cbNeeded)) {
        for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
            TCHAR szModName[MAX_PATH];
            if (GetModuleFileNameEx(h_lsass, hmods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
                if (wstring(szModName).find(L"NTDSA.dll") != string::npos) {
                    _tprintf(TEXT("%s\n"), szModName);
                    MODULEINFO lModInfo = { 0 };
                    if (GetModuleInformation(h_lsass, hmods[i], &lModInfo, sizeof(lModInfo))){
                        cout << "\t Base Addr: " << lModInfo.lpBaseOfDll << endl;
                        cout << "\t Entry Point: " << lModInfo.EntryPoint << endl;
                        cout << "\t Size of image: " << lModInfo.SizeOfImage << endl;

                        start_addr = (__int64*)lModInfo.lpBaseOfDll;
                        size_of_ntdsa = lModInfo.SizeOfImage;
                    }
                    else {
                        cout << "Failed to Print enumerated list of modules: " << GetLastError() << endl;
                    }
                }
            } else {
                cout << "Failed to Print enumerated list of modules: " << GetLastError() << endl;
            }
        }
    }
    else {
        cout << "Failed to enum the modules: " << GetLastError() << endl;
    }

    // Ready to continue?
    string cont = "";
    cout << "Continue? [Y|n]: ";
    getline(cin, cont);
    if (cont.find("n") != string::npos || cont.find("N") != string::npos) {
        CloseHandle(h_lsass);
        return 0;
    }

    void* buf = malloc(size_of_ntdsa);
    if (!buf) {
        cout << "Failed to allocate space for memory contents: " << GetLastError() << endl;
        CloseHandle(h_lsass);
        return -1;
    }

    SIZE_T num_bytes_read = 0;
    int count = 0;

    if (ReadProcessMemory(h_lsass, &start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) {
        cout << "Read success. Got " << num_bytes_read << " bytes: " << endl;
    } else {
        int error_code = GetLastError();
        if (error_code == 299) {
            cout << "Partial read. Got " << num_bytes_read << " bytes: " << endl;
        } else  {
            cout << "Failed to read memory: " << GetLastError() << endl;
            CloseHandle(h_lsass);
            free(buf);
            return -1;
        }
    }

    if (num_bytes_read > 0) {
        FILE *fp;
        fopen_s(&fp, "C:\\ntdsa_new.dll", "w");
        SIZE_T bytes_written = 0;
        while (bytes_written < num_bytes_read) {
            bytes_written += fwrite(buf, 1, num_bytes_read, fp);
        }
        fclose(fp);
        cout << "Wrote " << bytes_written << " bytes." << endl;
    }

    CloseHandle(h_lsass);
    free(buf);

    return 0;
}
4

1 に答える 1