2016-03-23 2 views
0

一部の学術研究のために、DLLの内容をメモリから読み取ろうとしています。具体的には、NTDSA.DLLライブラリは、プログラミングエラーをシミュレートしてシステムを強制的に失敗させる特定の命令を変更するためのものです。この失敗は、将来の失敗を予測するための機械学習アルゴリズムを学習するために記録されます(これは、これまでに公開された研究seen hereを一般化する試みです)。Win API予期しないデータを返すDLLのベースアドレスのReadProcessMemory

私は、hereで説明されているプロセスを通じてlsass.exeプロセス(ターゲットDLLを読み込む)の仮想メモリのベースアドレスと考えています。次に、割り当てられたバッファを持つReadProcessMemoryを呼び出し、 'PROCESS_ALL_ACCESS'が設定されたOpenProcessを呼び出して取得したlsassへのハンドルを取得します。 ReadProcessMemoryは、エラーコード299を返し、0バイトの読み込み時間(部分読み取り)の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; 
} 
+0

理由がわかりません。 – paullj1

+0

ReadProcessMemory()で(&)変数start_addrのアドレスを使用するのはなぜですか? – ssbssa

+1

ええと...私はC/C++を書いて以来ずっと長くなっていたので、それが問題でした。どのくらい私が目の2番目のセットに感謝するかは分かりません。 – paullj1

答えて

0

コードが説明したように動作マイナス私は、ターゲットアプリケーションの仮想メモリ内の位置のアドレスを格納するために使用した変数のアドレスを送信する私のアマチュアのミス。上記のコードでは、変更された:

if (ReadProcessMemory(h_lsass, &start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) { 

魔法のように

if (ReadProcessMemory(h_lsass, start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) { 

作品

へ。間違いを指摘していただきありがとうございました ssbssa、誰の時間を無駄にして申し訳ありません。

関連する問題