C++의 함수 호출 형태를 보면 3가지(_cdecl / _stdcall / _fastcall)가 있는것을 알것이다.
3가지를 간략히 정리해 보면
1. _cdecl
    - 파라미터 전달은 오른쪽에서 왼쪽 방향으로 스택을 이용
    - 파라미터 해제는 호출한 함수가 정리(그러므로 가변인자가 가능)
2. _stdcall
    - 파라미터 전달은 오른쪽에서 왼쪽 방향으로 스택을 이용
    - 파라미터 해제는 불려진 함수 내에서 정리
3. _fastcall
    - 처음 두개를 레지스터(ecx, edx)를 이용하고 나머지 파라미터를 오른쪼에서 왼쪽으로 스택을 이용
    - 파라미터 해제는 불려진 함수 내에서 정리
위와 같이 정리해 볼수 있다.

그럼 int sum(int a, int b)함수를 3가지로 구현해서 직접 확인해 보자.
첫번째로 아래 코드는 RETN시 스택을 정리 해주기 위한 부분이 없다. 이를 통해서 _cdecl을 이용해 구현한 함수 임을 파악해 볼 수 있다.


다음 코드를 보면 RETN 8을 통해 스택을 정리 해주는 것을 알 수 있다. 또한 ecx, edx를 사용하지 않았으므로 이는 _stdcall을 통해서 구현한 함수 임을 파악이 가능하다.

마지막으로 아래 코드를 보면 ECX와 EDX를 이용하 였다는 것을 알 수 있다. 하지만 _fastcall의 경우 불려진 함수 내에서 스택을 정리한다고 되어있는데 RETN시 스택을 정리 하는 부분이 없어 의아해 할 수 있다. 이는 ECX와 EDX레지스트만 이용하였기 때문에 스택을 정리 해줄 필요가 없기 때문이다. 아래의 함수는 _fastcall임을 알 수 있다.

위와같이 calling convetion을 이해하고 어셈코드의 구조를 파악하고 있다면 리버싱 단계에서 해당 함수의 calling convetion을 파악하고 코드화 하는데 휠씬 도움이 될것 이다.

Posted by hazeyun
,


Image Base Relocation

기준재배치..(exe파일은 예외)

pe파일이 메모리에 로드될 경우 .exe파일의 경우 가장 먼저 로드될 것이기 때문에 원하는 번지(0x00400000)에 로드될 수 있다.
하지만 .dll일 경우 하나의 실행파일에 여러개의 dll이 로드될 수 있으므로 원하는 번지(0x01000000)에 로드되긴 어렵다.
그럴때를 위해 pe파일에는 relocation정보를 담아두고 로드되기 원하는 번지와 실제 로드된 번지의 차이인 delta를 기준으로
재배치를 수행하게 된다.

이 재배치 정보는 IMAGE_OPTIONAL_HEADER의 Data Directory에 존재하고 인덱스값은 winnt.h에
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 라고 정의되어 있다.
또한 재배치섹션의 처음 시작정보를 담을 구조체는 아래와 같이 정의되어 있고
//
// Based relocation format.
//
typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;
//  WORD    TypeOffset[1];
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

위의 구조체 이후에 word데이터가 뒤따라 오게된다. 뒤따라 오는 word데이터는 상위 4bit는 타입정보를 하위 12bit는 오프셋값을 가진다.
VirtualAddress는 Rva를 담고있다. 따라서 재배치가 필요한 데이터는 (VirtualAddress + 오프셋) 한 값이 가리키는 데이터가 재배치가 필요한 값이다. (((VirtualAddress + 오프셋 이 가리키는값) - imageSize) + 실제 로드된 베이스번지) 를 하게 되면 재배치 정보고 완성되게 된다.

위의 이미지에서 빨간줄이 쳐진 부분이 바로 재배치가 필요한 부분이라 할수 있다.
예를 들자면 (앞의 주소부분+1)한 값이 재배치가 필요한 데이터를 가르키는 부분이 되겠고, 거기에 있는값이 재배치가 필요한 데이터가 되겠다.

Posted by hazeyun
,
파일의 Access Time 이란 것이 존재한다.
당연하게도 이것은 파일이 Access된 시간을 가지고 있게된다.

그럼 이 Access Time을 얻어오려면 ...
CreateFile함수로 파일을 열어 파일의 Handle을 얻고, 얻어온 핸들을 통해서 GetFileInformationByHandle함수를 통해서 파일정보를 얻어올 수 있다.
하지만 CreateFile 하는 순간 벌써 파일에 접근하게 된다. 그럼 당연히 Access Time이 갱신 될 것이고 얻으려고 하는 Access Time을 얻어올 수 없다. 하지만 CreateFile의 두번째 인자로 FILE_READ_ATTRIBUTES속성을 주게되면 Access Time을 변경하지 않고 핸들만 얻어와서 파일 정보를 얻오 올 수 있게 된다.

아래는 테스트 코드이다.


Posted by hazeyun
,

Dialog에서 상태바 표시하기...

Step1. Dialog base의 프로젝트 생성...

Step2. indicator를 위해 ResourceSymbol에 ID_INDICATOR_TEST1, ID_INDICATOR_TEST2를 추가하고, string table에 string을 설정해 준다. (참고로 string table은 4번째 스샷에 파란 부분을 더블클릭 해주면 된다.)


위와 같이 하면 리소스 부분은 완료다.

Step3. 이제 Dialog클래스에 멤버 변수로 CStatusBar타입의 변수 하나를 생성한다.

Step4. Dialog클래스의 OnInitDialog() function에 초기화 코드를 삽입해준다.


Step5. build 후 실행 .



아래에 소스코드 첨부...
Posted by hazeyun
,

OpenProcess함수는 프로세스에 할당된 가상메모리를 Read/WriteProcessMemory를 이용하여 조작하기 위하여  많은 사람들이 사용하는 함수일 것이다. 물론 악의적으로도, 보안을 위해서도 사용되어 질 수 있다.

.
.
.

XP에서 Read/Write를 위해서는 간단히
HANDLE hTarget = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
를 해주면 된다. 그렇게 되면 해당 프로세스의 가상메모리에 접근할 수 있게 된다. 이 얼마나 간단한가!

.
.
.

But!!!!

.
.
.

망할 Vista......!
저렇게 해주고 실행파일을 생성해서 실행시키면 간단히 OpenProcess함수가 ERROR_ACCESS_DENIED!! 토해 주신다.. 어처구니 짜장이다.. 분명히 XP에서는 잘 돌아 갔더랬다. 잘나신 Vista의 관리자 모드 때문이다.!
열받아서 UAC를 무시하겠다 라고 맘먹었으나...... 구글링에 삽질의 삽질끝에 이미 태생이 관리자 모드가 아닌 프로세스는 별의 별짓을 다해도 남의 프로세스를 열수가 없더라~!

그래서 ShellExecuteEx를 사용해서 관리자 권한을 유도 하는 방법으로 커버했다...젠장!
Posted by hazeyun
,

일반적인 프로그램들을 보면 프로그램이 실행되어 있을경우 다시 실행 시키면 하나더 생기지 않고 기존에 생성되 있는 프로그램으로 포커스가 가능 경우가 있다.
보통의 mfc프로그램을 작성하면 이런 기능은 없다. 하지만 추가도 쉽고 의외로 쓸모도 있을것 이다.
 
Posted by hazeyun
,

Posted by hazeyun
,
main.h


main.cpp


test.cpp


단방에 오류 뜨는구나...

static키워드의 의미를 지금껏 반쪽밖에 이해하지 못하고 있었구나.. 무지하도다..ㅋ
Posted by hazeyun
,
작업 관리자 따라해 보려고 알아보 던중 CreateToolhelp32Snapshot라는 api를 찾았다.
첨 보는 함수 였는데 꽤 알려져 있는지 웹서핑에 쉽게 찾아 볼 수 있었다.

일단 뭐하는 함수 인고 하니...
HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32processID);
정의된 플래그와 프로세스id를 받아서 핸들을 넘겨주게 되어있다. 그리고 이 넘겨받은 핸들을 이용하여 루프를 돌면서 Process32FirstProcess32Next를 사용하여 프로세스의 정보들을 얻어올 수 있다.
프로세스의 정보는 PROCESSENTRY32라는 구조체에 담아진다.


자세한 정보는 여기를 들어가 보길..

그럼 위의 것들을 이용하여 간단히 프로세스 이름과 아이디를 출력하는 프로그램이다.


참고로 위의 CreateToolhelp32Snapshot, Process32First..등등 을 사용하기 위해 <tlhelp32.h>꼭 포함시켜 줘야 한다.
Posted by hazeyun
,

WM_CTLCOLORSTATIC - static control 색상을 변경할 때 사용
WM_CTLCOLORBTN      - button control 색상을 변경할 때 사용
WM_CTLCOLOREDIT     - editbox control 색상을 변경할 때 사용

사용예..

HBRUSH    hBrush_Control;

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
       switch(msg)
       {
        case WM_CREATE:
                 hBrush_Contorl = CreateSolidBrush(RGB(255, 255, 255));   //흰색 브러시 생성.
                   ...
                 return 0;
        case WM_CTLCOLORSTATIC:
                 SetBKColor((HDC)wParam, RGB(255, 255, 255);
                 return (LRESULT)hBrush_Control;
        }
}

대충 이런 식으로 사용한다.
lParam으로 특정 컨트롤의 색상만 변경도 가능하다.
if((HWND)lParam == hWnd_static01)
{
      //컨트롤에 대한 색상처리...
}

버튼같은경우 안먹던데ㅡ_ㅡ. 그리고 처음 브러쉬를 생성할때 색상이랑 SetBkColor함수에 넣어줄 t색상이랑 맞춰주는게 나을꺼 같다. static control의 경우 글자 주위의 배경색만 바뀌는거 같다.

Posted by hazeyun
,