2012-11-10 4 views
1

오늘, 나는 소스 주입을 설명하는 기사 (http://www.codeproject.com/KB/threads/winspy.aspx)를 읽었으며 같은 것을하기위한 프로그램을 작성하려고합니다 . 하지만 나는 winmind에 소스를 주입하고 충돌합니다. 나는 추락의 이유를 발견 할 수 없다.소스 주입 및 프로그램 충돌

가 가

내 코드 :

코드 원격 프로세스

static int WINAPI ThreadFunc (INJDATA *pData) 
{ 
    int nXferred = 0; 

    nXferred = pData->fnMessageBox(pData->hwnd, (LPCWSTR)pData->pbText, (LPCWSTR)pData->pbTextCap, pData->type); 
    pData->pbText [63 * sizeof(TCHAR)] = __TEXT('\0'); 
    pData->pbTextCap [63 * sizeof(TCHAR)] = __TEXT('\0');  

    return nXferred; 
} 


// This function marks the memory address after ThreadFunc. 
// int cbCodeSize = (PBYTE) AfterThreadFunc - (PBYTE) ThreadFunc. 
static void AfterThreadFunc (void) { 
} 

3.Copies ThreadFunc 및 INJDATA 주입하고되는

typedef LRESULT (WINAPI *MESSAGEBOX)(HWND, LPCWSTR, LPCWSTR, UINT);

typedef struct { 
HWND hwnd; 
    UINT type; 
    MESSAGEBOX fnMessageBox;   // pointer to user32!SendMessage 
    BYTE pbText[64 * sizeof(TCHAR)]; // text param 
    BYTE pbTextCap[64 * sizeof(TCHAR)]; // caption param 
} INJDATA, *PINJDATA; 

2. 1.describe의 분사 데이터 구조체 시작 원격 ThreadFunc의 예기치

int CallMessageBox (HANDLE hProcess, HWND hWnd, LPCWSTR pbString, LPCWSTR pbStringCap) 
{ 
    HINSTANCE hUser32; 
    INJDATA  *pDataRemote; // the address (in the remote process) where INJDATA will be copied to; 
    DWORD  *pCodeRemote; // the address (in the remote process) where ThreadFunc will be copied to; 
    HANDLE  hThread = NULL; // the handle to the thread executing the remote copy of ThreadFunc; 
    DWORD  dwThreadId = 0; 

    int  nCharsXferred = 0; // number of chars retrieved by WM_GETTEXT in the remote thread; 
    DWORD dwNumBytesXferred = 0; // number of bytes written/read to/from the remote process; 

    __try { 
     hUser32 = GetModuleHandle(__TEXT("user32")); 
     if (hUser32 == NULL) 
      __leave; 

     // Initialize INJDATA and then 
     // copy it to the remote process 
     INJDATA DataLocal = { 
      hWnd, 
      MB_OK, 
      (MESSAGEBOX) GetProcAddress(hUser32, "MessageBoxW")   
     }; 

     if(DataLocal.fnMessageBox == NULL) 
      __leave;   

     wcscpy((LPWSTR) DataLocal.pbText, (LPCWSTR) pbString); 
     wcscpy((LPWSTR) DataLocal.pbTextCap, (LPCWSTR) pbStringCap); 

     // 1. Allocate memory in the remote process for INJDATA 
     // 2. Write a copy of DataLocal to the allocated memory 
     pDataRemote = (INJDATA*) VirtualAllocEx(hProcess, 0, sizeof(INJDATA), MEM_COMMIT, PAGE_READWRITE); 
     if (pDataRemote == NULL) 
      __leave; 
     WriteProcessMemory(hProcess, pDataRemote, &DataLocal, sizeof(INJDATA), &dwNumBytesXferred); 


     // Calculate the number of bytes that ThreadFunc occupies 
     const int cbCodeSize = ((LPBYTE) AfterThreadFunc - (LPBYTE) ThreadFunc); 

     // 1. Allocate memory in the remote process for the injected ThreadFunc 
     // 2. Write a copy of ThreadFunc to the allocated memory 
     pCodeRemote = (PDWORD) VirtualAllocEx(hProcess, 0, cbCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);  
     if (pCodeRemote == NULL) 
      __leave; 
     WriteProcessMemory(hProcess, pCodeRemote, &ThreadFunc, cbCodeSize, &dwNumBytesXferred); 


     // Start execution of remote ThreadFunc 
     hThread = CreateRemoteThread(hProcess, NULL, 0, 
       (LPTHREAD_START_ROUTINE) pCodeRemote, 
       pDataRemote, 0 , &dwThreadId); 
     if (hThread == NULL) 
      __leave; 

     WaitForSingleObject(hThread, INFINITE); 

     } 
    __finally { 

     if (pDataRemote != 0) 
      VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE); 

     if (pCodeRemote != 0) 
      VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE); 

     if (hThread != NULL) { 
      GetExitCodeThread(hThread, (PDWORD) &nCharsXferred); 
      CloseHandle(hThread);   
     } 
    } 

    // Return the number of chars retrieved 
    return nCharsXferred; 
} 

답변

3

불행히도이 설명은 유효 기간이 지났습니다. 최신 버전의 Windows에는 ASLR (Address space layout randomization)이라는 보호 기능이 있습니다. 기본 코드 주입으로부터 코드를 보호하고 각 프로세스마다 고유 한 주소 공간을 보장합니다. 모든 프로세스가 ASLR을 사용할 수있는 것은 아니지만 대부분의 경우 오래된 기술은 적합하지 않습니다.

편집 : 삽입 된 코드가 실행되었는데 충돌이 있습니까? 그렇다면 EIP 레지스터가 증가하지만 주입 된 쉘 코드에서 실행할 명령이 더 이상 없기 때문일 수 있습니다. 할당 된 메모리에 명령 포인터를 설정하고 코드를 실행했지만 해당 프로세스가 더 이상 유효한 명령을 실행하지 않으면 실행합니다. 이를 방지하기 위해 더 많은 메모리를 할당하고 간단히 무한 루프를 반복하는 간단한 쉘 코드를 작성하여 EIP가 메모리에있는 임의의 항목을 실행하지 못하도록합니다.

+0

예, 저는 virtul 시스템과 winXP에서 이것을 시도하지만 messageBox를 닫으면 winmine이 중단됩니다. 왜 그런지 모르겠다. – wenz

+0

내 게시물을 편집합니다. 1 ~ 2 분 안에 확인해보십시오. –

+0

Yob, 고마워요. :) – wenz