1. TEB에서 값 얻어오기
2. 커널 상속( 콘솔 창에 출력을 edit박스로 받기 )
//-------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
switch( msg )
{
case WM_CREATE:
{
hEdit = CreateWindow( "edit", "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
10, 10, 500, 500, hwnd, (HMENU)1, 0, 0 );
}
return 0;
case WM_LBUTTONDOWN:
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(si) };
// 화일을 생성해서 ping의 표준 출력을 redirect 한다.
HANDLE hFile = CreateFile(
"a.txt", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0 );
// 모든 KO는 기본적으로 상속 불가능
// 특정 KO를 상속 가능하게 변경한다.
SetHandleInformation( hFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
si.hStdOutput = hFile; // 표준 출력과 연결할 파일 핸들을 지정한다.
si.dwXSize = 100;
si.dwYSize = 100; // 자식이 만드는 윈도우의 크기를 지정한다.
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE;
//----------------------------------------------------------------
char cmd[256] = "ping www.dblab.co.kr";
BOOL b = CreateProcess(
0, cmd, 0, 0, TRUE,
CREATE_NO_WINDOW, // 콘솔에서 만들지 말라.//우선순위 | 플래그
0, 0, &si, &pi );
if( b )
{
// ping이 종료될 때까지 대기한다.
WaitForSingleObject( pi.hProcess, INFINITE );
// 이제 파일에서 읽어 온다.
char buf[8096] = { 0 }; // 8k 버퍼
// 파일 포인터를 처음으로 옮기고. 4G가 보다 클수 있으므로 크기를 알려준다.
SetFilePointer( hFile, 0, 0, FILE_BEGIN );
DWORD len;
ReadFile( hFile, buf, 8096, &len, 0 );
// EditBox에 출력해준다.
SetWindowText( hEdit, buf );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
3. Pipe를 사용한 콘솔창 출력을 에디트 박스로~( 한줄 씩 읽어보기 )
3. 실행중인 프로세스 열거해보기
4. pid 를 사용한 모듈 열거
5. PC끄는 권한 얻어 와서 종료시키기
more..
// GetLastError() 함수의 원리 - 스레드당 1개의 에러코드를 얻는 함수.(TEB에 있다.)
int get_last_error()
{
int err = 0;
__asm
{
// TEB의 0x34번째 값을 얻는다.
mov eax, FS:[0x34]
mov err, eax
}
return err;
}
// 현재 프로세스가 디버깅 중인지 알아낸다. - Anti hack 프로그램의 원리
int AntiHack()
{
char bRet = 0;
__asm
{
// PEB의 주소를 알아낸다.
mov eax, FS:[0x30]
// PEB에서 2byte 이동한다.
add eax, 2
// 디버깅 중인지를 알아낸다.
mov bl, byte ptr[eax]
mov bRet, bl
}
return bRet;
}
// 현재 쓰레드의 Id를 알아낸다.
int MyGetCurrentThreadId()
{
int tid = 0;
__asm
{
mov eax, FS:[0x24]
mov tid, eax
}
return tid;
}
// 현재 스택의 시작주소를 알아낸다.
PVOID MyGetStackBase()
{
PVOID tid = 0;
__asm
{
mov eax, FS:[0x04]
mov tid, eax
}
return tid;
}
// TLS의 주소를 알아온다.
PVOID MyGetThreadLocalStorage()
{
PVOID tid = 0;
__asm
{
mov eax, FS:[0x2c]
mov tid, eax
}
return tid;
}
int get_last_error()
{
int err = 0;
__asm
{
// TEB의 0x34번째 값을 얻는다.
mov eax, FS:[0x34]
mov err, eax
}
return err;
}
// 현재 프로세스가 디버깅 중인지 알아낸다. - Anti hack 프로그램의 원리
int AntiHack()
{
char bRet = 0;
__asm
{
// PEB의 주소를 알아낸다.
mov eax, FS:[0x30]
// PEB에서 2byte 이동한다.
add eax, 2
// 디버깅 중인지를 알아낸다.
mov bl, byte ptr[eax]
mov bRet, bl
}
return bRet;
}
// 현재 쓰레드의 Id를 알아낸다.
int MyGetCurrentThreadId()
{
int tid = 0;
__asm
{
mov eax, FS:[0x24]
mov tid, eax
}
return tid;
}
// 현재 스택의 시작주소를 알아낸다.
PVOID MyGetStackBase()
{
PVOID tid = 0;
__asm
{
mov eax, FS:[0x04]
mov tid, eax
}
return tid;
}
// TLS의 주소를 알아온다.
PVOID MyGetThreadLocalStorage()
{
PVOID tid = 0;
__asm
{
mov eax, FS:[0x2c]
mov tid, eax
}
return tid;
}
2. 커널 상속( 콘솔 창에 출력을 edit박스로 받기 )
more..
//-------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
switch( msg )
{
case WM_CREATE:
{
hEdit = CreateWindow( "edit", "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
10, 10, 500, 500, hwnd, (HMENU)1, 0, 0 );
}
return 0;
case WM_LBUTTONDOWN:
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(si) };
// 화일을 생성해서 ping의 표준 출력을 redirect 한다.
HANDLE hFile = CreateFile(
"a.txt", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0 );
// 모든 KO는 기본적으로 상속 불가능
// 특정 KO를 상속 가능하게 변경한다.
SetHandleInformation( hFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
si.hStdOutput = hFile; // 표준 출력과 연결할 파일 핸들을 지정한다.
si.dwXSize = 100;
si.dwYSize = 100; // 자식이 만드는 윈도우의 크기를 지정한다.
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE;
//----------------------------------------------------------------
char cmd[256] = "ping www.dblab.co.kr";
BOOL b = CreateProcess(
0, cmd, 0, 0, TRUE,
CREATE_NO_WINDOW, // 콘솔에서 만들지 말라.//우선순위 | 플래그
0, 0, &si, &pi );
if( b )
{
// ping이 종료될 때까지 대기한다.
WaitForSingleObject( pi.hProcess, INFINITE );
// 이제 파일에서 읽어 온다.
char buf[8096] = { 0 }; // 8k 버퍼
// 파일 포인터를 처음으로 옮기고. 4G가 보다 클수 있으므로 크기를 알려준다.
SetFilePointer( hFile, 0, 0, FILE_BEGIN );
DWORD len;
ReadFile( hFile, buf, 8096, &len, 0 );
// EditBox에 출력해준다.
SetWindowText( hEdit, buf );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
3. Pipe를 사용한 콘솔창 출력을 에디트 박스로~( 한줄 씩 읽어보기 )
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hEdit;
switch( msg )
{
case WM_CREATE:
{
hEdit = CreateWindow( "edit", "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
10, 10, 500, 500, hwnd, (HMENU)1, 0, 0 );
}
return 0;
case WM_LBUTTONDOWN:
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(si) };
HANDLE hRead, hWrite;
CreatePipe( &hRead, &hWrite, 0, 1024 );
SetHandleInformation( hWrite, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
si.hStdOutput = hWrite; // 쓰기 위한 Pipe 핸들을 전달한다.
si.dwFlags = STARTF_USESTDHANDLES;
char cmd[256] = "ping www.dblab.co.kr";
BOOL b = CreateProcess( 0, cmd, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &si, &pi );
if( b )
{
CloseHandle( hWrite ); // 이제 쓰기 위한 핸들은 필요없다.
while( 1 )
{
char buf[2048] = { 0 }; // 2k 버퍼
DWORD len;
BOOL b = ReadFile( hRead, buf, 2048, &len, 0 ); // 파이프로 결국 파일
if( len <= 0 ) // 에러 발생이거나 파이프가 닫힌 경우
break;
// 에디트에 한줄 씩 추가한다.
SendMessage( hEdit, EM_REPLACESEL, 0, (LPARAM)buf );
}
CloseHandle( hRead );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
{
static HWND hEdit;
switch( msg )
{
case WM_CREATE:
{
hEdit = CreateWindow( "edit", "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
10, 10, 500, 500, hwnd, (HMENU)1, 0, 0 );
}
return 0;
case WM_LBUTTONDOWN:
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(si) };
HANDLE hRead, hWrite;
CreatePipe( &hRead, &hWrite, 0, 1024 );
SetHandleInformation( hWrite, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
si.hStdOutput = hWrite; // 쓰기 위한 Pipe 핸들을 전달한다.
si.dwFlags = STARTF_USESTDHANDLES;
char cmd[256] = "ping www.dblab.co.kr";
BOOL b = CreateProcess( 0, cmd, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &si, &pi );
if( b )
{
CloseHandle( hWrite ); // 이제 쓰기 위한 핸들은 필요없다.
while( 1 )
{
char buf[2048] = { 0 }; // 2k 버퍼
DWORD len;
BOOL b = ReadFile( hRead, buf, 2048, &len, 0 ); // 파이프로 결국 파일
if( len <= 0 ) // 에러 발생이거나 파이프가 닫힌 경우
break;
// 에디트에 한줄 씩 추가한다.
SendMessage( hEdit, EM_REPLACESEL, 0, (LPARAM)buf );
}
CloseHandle( hRead );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
3. 실행중인 프로세스 열거해보기
more..
#include <tlhelp32.h>
// TOOL Help API : process, thread, module, heap 등을 열거 할때 사용하는 API의 모음
// kernel32.dll 에 있다.
BOOL EnablePrimary( HANDLE hProcess, // 권한을 부여할 프로세스
char* pri, // 권한을 나타내는 문자열
BOOL bEnable // 가능/불가능 여부
)
{
HANDLE hToken;
OpenProcessToken( hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken );
// 문자열로 되어 있는 권한ID( LUID, 64비트 정수 )로 변경한다.
LUID luid;
LookupPrivilegeValue(
".", // PC이름
pri, // 권한이름
&luid ); // luid를 담을 변수
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1; // 갯수
tp.Privileges[0].Luid = luid; // 권한 ID
tp.Privileges[0].Attributes= bEnable ? SE_PRIVILEGE_ENABLED : 0;
return AdjustTokenPrivileges( hToken, 0, &tp, sizeof(tp), 0, 0 );
}
int main()
{
if ( EnablePrimary(
GetCurrentProcess(), // 현재 프로세스의 핸들(-1이 나온다. -1은 자신을의미)
SE_SHUTDOWN_NAME, TRUE ) // PC를 종료할수 있는 특권.
== FALSE )
{
printf("can't Get Privieges\n");
return 0;
}
// 프로세스의 목록을 메모리 어딘가에 보관(snapshot)해 둔다.
HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof( pe32 );
BOOL b = Process32First( hSnap, &pe32 );
while( b )
{
printf( "%04d %04d %s\n",
pe32.th32ProcessID,
pe32.th32ParentProcessID,
pe32.szExeFile );
b = Process32Next( hSnap, &pe32 );
}
CloseHandle( hSnap );
}
// TOOL Help API : process, thread, module, heap 등을 열거 할때 사용하는 API의 모음
// kernel32.dll 에 있다.
BOOL EnablePrimary( HANDLE hProcess, // 권한을 부여할 프로세스
char* pri, // 권한을 나타내는 문자열
BOOL bEnable // 가능/불가능 여부
)
{
HANDLE hToken;
OpenProcessToken( hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken );
// 문자열로 되어 있는 권한ID( LUID, 64비트 정수 )로 변경한다.
LUID luid;
LookupPrivilegeValue(
".", // PC이름
pri, // 권한이름
&luid ); // luid를 담을 변수
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1; // 갯수
tp.Privileges[0].Luid = luid; // 권한 ID
tp.Privileges[0].Attributes= bEnable ? SE_PRIVILEGE_ENABLED : 0;
return AdjustTokenPrivileges( hToken, 0, &tp, sizeof(tp), 0, 0 );
}
int main()
{
if ( EnablePrimary(
GetCurrentProcess(), // 현재 프로세스의 핸들(-1이 나온다. -1은 자신을의미)
SE_SHUTDOWN_NAME, TRUE ) // PC를 종료할수 있는 특권.
== FALSE )
{
printf("can't Get Privieges\n");
return 0;
}
// 프로세스의 목록을 메모리 어딘가에 보관(snapshot)해 둔다.
HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof( pe32 );
BOOL b = Process32First( hSnap, &pe32 );
while( b )
{
printf( "%04d %04d %s\n",
pe32.th32ProcessID,
pe32.th32ParentProcessID,
pe32.szExeFile );
b = Process32Next( hSnap, &pe32 );
}
CloseHandle( hSnap );
}
4. pid 를 사용한 모듈 열거
more..
#include <tlhelp32.h>
int main( int argc, char** argv ) { if ( argc != 2 )
{
printf( "usage : %s <pid> \n", argv[0] );
return 0;
}
DWORD pid = atoi( argv[1] );
HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
MODULEENTRY32 me32 = { sizeof(me32) };
BOOL b = Module32First( hSnap, &me32 );
while( b )
{
printf( "%08x : %s\n", me32.modBaseAddr, me32.szModule );
b = Module32Next( hSnap, &me32 );
}
CloseHandle( hSnap );
}
int main( int argc, char** argv ) { if ( argc != 2 )
{
printf( "usage : %s <pid> \n", argv[0] );
return 0;
}
DWORD pid = atoi( argv[1] );
HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
MODULEENTRY32 me32 = { sizeof(me32) };
BOOL b = Module32First( hSnap, &me32 );
while( b )
{
printf( "%08x : %s\n", me32.modBaseAddr, me32.szModule );
b = Module32Next( hSnap, &me32 );
}
CloseHandle( hSnap );
}
5. PC끄는 권한 얻어 와서 종료시키기
more..
// 특정 프로세스에 특정 권한을 부여한다. - 이 함수 역시 관리자 모드이어야만 실행이 성공.
BOOL EnablePrimary( HANDLE hProcess, // 권한을 부여할 프로세스
char* pri, // 권한을 나타내는 문자열
BOOL bEnable // 가능/불가능 여부
)
{
HANDLE hToken;
OpenProcessToken( hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken );
// 문자열로 되어 있는 권한ID( LUID, 64비트 정수 )로 변경한다.
LUID luid;
LookupPrivilegeValue(
".", // PC이름
pri, // 권한이름
&luid ); // luid를 담을 변수
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1; // 갯수
tp.Privileges[0].Luid = luid; // 권한 ID
tp.Privileges[0].Attributes= bEnable ? SE_PRIVILEGE_ENABLED : 0;
return AdjustTokenPrivileges( hToken, 0, &tp, sizeof(tp), 0, 0 );
}
int main()
{
// PC를 끌수 있는 권한을 부여한다.
if ( EnablePrimary(
GetCurrentProcess(), // 현재 프로세스의 핸들(-1이 나온다. -1은 자신을의미)
SE_SHUTDOWN_NAME, TRUE ) // PC를 종료할수 있는 특권.
== FALSE )
{
printf("can't Get Privieges\n");
return 0;
}
// 컴퓨터를 종료 하는 함수
BOOL b = ExitWindowsEx( EWX_POWEROFF, 0 );
if( b == FALSE )
{
printf( "실패 : %d\n", GetLastError() );
}
}
BOOL EnablePrimary( HANDLE hProcess, // 권한을 부여할 프로세스
char* pri, // 권한을 나타내는 문자열
BOOL bEnable // 가능/불가능 여부
)
{
HANDLE hToken;
OpenProcessToken( hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken );
// 문자열로 되어 있는 권한ID( LUID, 64비트 정수 )로 변경한다.
LUID luid;
LookupPrivilegeValue(
".", // PC이름
pri, // 권한이름
&luid ); // luid를 담을 변수
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1; // 갯수
tp.Privileges[0].Luid = luid; // 권한 ID
tp.Privileges[0].Attributes= bEnable ? SE_PRIVILEGE_ENABLED : 0;
return AdjustTokenPrivileges( hToken, 0, &tp, sizeof(tp), 0, 0 );
}
int main()
{
// PC를 끌수 있는 권한을 부여한다.
if ( EnablePrimary(
GetCurrentProcess(), // 현재 프로세스의 핸들(-1이 나온다. -1은 자신을의미)
SE_SHUTDOWN_NAME, TRUE ) // PC를 종료할수 있는 특권.
== FALSE )
{
printf("can't Get Privieges\n");
return 0;
}
// 컴퓨터를 종료 하는 함수
BOOL b = ExitWindowsEx( EWX_POWEROFF, 0 );
if( b == FALSE )
{
printf( "실패 : %d\n", GetLastError() );
}
}