리소스 다루기 2

programming/windows 2012. 5. 24. 09:21
루트킷 같은 성격의 드라이버들은 배포시 아래와 같은 방법으로 
실행 바이너리의 리소스에 드라이버를 포함시킨다.




리소스 추가 -> 가져오기( 드라이버 파일) -> 사용자 지정 리소스 탐색 (ex:Driver) 
와 같이 추가를 하면 아래의 그림처럼 바이너리가 추가된다.




그 후 Build를 하면 내가 포함 시킨 드라이버 파일과 Resource.h 파일이 수정된다.





아래의 IDR_DRIVER1의 선언해준 "DRIVER"를 통해 리소스를 추출하면 된다.



[Source]
BOOL ExtractDriver(LPSTR Path)
{
  HRSRC RsH;
  HGLOBAL RsGH;
  BYTE *FilePtr;
  ULONG FileSize;
  ULONG numWritten;
  HANDLE hFile;
  RsH = FindResource(NULL, MAKEINTRESOURCE(IDR_DRIVER1), "DRIVER");
  if(!RsH)
  {
   printf( "FindResource Error\n" );
   return FALSE;
  }
  RsGH = LoadResource(NULL, RsH);
  if(!RsGH)
  {
   printf( "LoadResource Error\n" );
   return FALSE;
  }
  FileSize = SizeofResource(NULL, RsH);
  FilePtr = (unsigned char *)LockResource(RsGH);
  if(!FilePtr)
  {
   printf( "LockResource Error\n" );
   return FALSE;
  }
  hFile = CreateFile( Path ,FILE_ALL_ACCESS,0,NULL,CREATE_ALWAYS,0, NULL);
  if(INVALID_HANDLE_VALUE == hFile)
  {
   return FALSE;
  }
  WriteFile(hFile, FilePtr, FileSize , &numWritten, NULL);
  CloseHandle(hFile);
  return TRUE;
}
BOOL CleanUp(LPSTR Path)
{
 if(S_OK != DeleteFile(Path))
 {
  return FALSE;
 }
 return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
 if( ExtractDriver( "C:\\ABCD.SYS" ) )
 {
 //-------------------------------
 //드라이버 로드
 //-------------------------------

 CleanUp( "C:\\ABCD.SYS" );
 }
 return 0;
}


출처 : http://wezz.tistory.com/entry/Win32-%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84-%ED%8C%8C%EC%9D%BC-Resource%EC%97%90-%ED%8F%AC%ED%95%A8%EC%8B%9C%ED%82%A4%EA%B8%B0


'programming > windows' 카테고리의 다른 글

str ansi uni multi  (0) 2015.11.03
VC2010/2012에 WTL 설치  (0) 2013.10.11
리소스 다루기 1  (0) 2012.05.23
까먹지말자  (0) 2012.02.28
Win32 Ref.  (0) 2011.12.27
:

리소스 다루기 1

programming/windows 2012. 5. 23. 09:51

디버그뷰나 프로세스 익스플로러같은 프로그램을 보면 실행 파일 하나로 구성되어 있는데 프로그램을 실행하면 드라이버를 로딩하는 것을 볼 수 있습니다. 어떻게 하는 걸까요? 답은 간단한데요. 해당 드라이버 파일을 리소스에 포함시켜 놓고 런타임에 풀어서 사용하는 방식입니다. 리소스에 추가하는 방법은 간단합니다. Visual Studio 리소스 뷰에서 오른쪽 클릭하시고 임포트 하시면 됩니다. sys 파일 같은건 안보이시죠. *.*로 필터링한다음 추가하시면 됩니다. 그러면 어떤 타입을 추가할지 물어볼텐데요. 아무렇게나 이름을 지어 주시면 됩니다. Binary 이런 식으로요. 자 그렇다면 이제 이렇게 추가된 리소스 파일을 런타임에 어떻게 조작하는지를 알아보도록 합시다.

조작하는 API는 소 심플합니다. FindResource, LoadResource, SizeOfResource, LockResource라는 API가 사용됩니다. 각각의 함수 사용 방법을 알아보도록 합시다.

  1. HRSRC FindResource(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType);  

FindResource 함수입니다. 이 함수는 우리가 분리해 내려고 하는 리소스를 찾는데 사용됩니다. hModule에는 리소스를 찾을 DLL의 모듈 핸들을 넣어주면 됩니다. NULL을 전달하면 현재 프로세스의 실행 파일 모듈에서 찾습니다. lpName에는 리소스 이름을 전달합니다. MAKEINTRESOURCE를 사용해서 리소스 ID를 문자열로 변환한 것을 대입해 주면 됩니다. 리소스 ID가 IDR_BINARY1이라면 MAKEINTRESOURCE(IDR_BINARY1)을 전달하면 되겠죠. lpType에는 리소스 타입을 넣어줍니다. 리소스 타입이 Binary라면 “Binary”를 전달하면 됩니다. 이렇게 넣어주면 리소스를 찾아서 해당 리소스의 핸들을 넘겨줍니다. 실패하면 NULL이 리턴되겠죠.

  1. DWORD SizeofResource(HMODULE hModule, HRSRC hResInfo);  

러소스의 크기를 구할 때 사용하는 함수입니다. hModule에는 모듈 핸들을 hResInfo에는 FindResource를 통해서 찾은 리소스 핸들을 넣어줍니다. 성공한 경우에는 리소스 크기를, 실패한 경우에는 0을 리턴합니다.

  1. HGLOBAL LoadResource(HMODULE hModule, HRSRC hResInfo);  

리소스를 로드하는 함수입니다. hModule에는 모듈 핸들을 hResInfo에는 FindResource로 찾은 리소스 핸들을 전달하면 되겠습니다. 해당 리소스의 포인터가 리턴됩니다.

  1. LPVOID LockResource(HGLOBAL hResData);  

마지막 함수입니다. LoadResource 한 메모리의 실제 포인터를 반환합니다. hResData에는 LoadResource에서 반환한 포인터를 넣어줍니다. 그럼 실제 포인터가 리턴됩니다.

종합해서 함수 하나로 만들어 봅시다. GetResourceInfo라는 함수입니다. module에서 type, name의 리소스를 찾아서 해당 리소스의 포인터를 data에 크기를 rsize에 있는지 없는지를 리턴 값으로 리턴해 주는 함수입니다.

  1. BOOL WINAPI GetResourceInfo(HMODULE module   
  2.                             , LPCTSTR type   
  3.                             , LPCTSTR name   
  4.                             , PVOID *data   
  5.                             , SIZE_T *rsize)   
  6. {   
  7.     DWORD size;   
  8.     HGLOBAL mem;   
  9.     PVOID ptr;   
  10.     HRSRC src;   
  11.   
  12.     src = FindResourceW(module, name, type);   
  13.     if(!src)   
  14.         return FALSE;   
  15.   
  16.     size = SizeofResource(module, src);   
  17.     if(!size)   
  18.         return FALSE;   
  19.   
  20.     mem = LoadResource(module, src);   
  21.     if(!mem)   
  22.         return FALSE;   
  23.   
  24.     ptr = LockResource(mem);   
  25.     if(!ptr)   
  26.         return FALSE;   
  27.   
  28.     __try  
  29.     {   
  30.         if(data)   
  31.             *data = ptr;   
  32.   
  33.         if(rsize)   
  34.             *rsize = size;   
  35.     }   
  36.     __except(EXCEPTION_EXECUTE_HANDLER)   
  37.     {   
  38.         return FALSE;   
  39.     }   
  40.   
  41.     return TRUE;   
  42. }  

여기까지만 설명하고 마칠까 하는데 아마 똑똑한 분들이라면 먼가 찜찜한 기분이 드실 거예요. 화장실가서 볼 일 보고 뭔가 정리하지 않고 나온 느낌이겠죠. 실컷 로딩하고 락하고 했는데 그것들을 해제하는 작업에 대해서는 하나도 설명하지 않았으니 말입니다. UnlockResource, FreeResource와 같은 함수들이 있긴 한데, 그것들은 사용하지 않아도 됩니다. 왜냐하면 여기서 사용하는 리소스 핸들을 구하고 하는 함수들은 로드된 모듈에서 포인터를 참조해 오는 일이거든요. 여러분이 획득한 모든 포인터 내지는 리소스는 hModule이 FreeLibrary 되는 시점에 같이 사라집니다. 따라서 별도로 해제할 필요가 없는 셈이죠. 참고로 그래도 나는 해제하겠다고 UnlockResource, FreeResource를 호출한들 실제 해당 함수에서 하는 일은 return 밖에는 없답니다.

출처 : http://www.jiniya.net/wp/archives/4366


'programming > windows' 카테고리의 다른 글

VC2010/2012에 WTL 설치  (0) 2013.10.11
리소스 다루기 2  (0) 2012.05.24
까먹지말자  (0) 2012.02.28
Win32 Ref.  (0) 2011.12.27
까먹까먹하는 PE rewrite  (0) 2011.09.16
:

exeDB

gravity-free/exeInfo 2012. 5. 21. 15:44

'gravity-free > exeInfo' 카테고리의 다른 글

www.liutilities.com  (0) 2012.05.09
www.windowexe.com  (0) 2012.05.08
: