레이블이 Dev인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Dev인 게시물을 표시합니다. 모든 게시물 표시

2013-10-05

InstallFactory


InstallFactory(인스톨팩토리) v2.70을 이용하여 VB로 만든 프로그램 배포하는 방법입니다.

작성자 : 김재우(http://yahoo.sy.to)
----------------------------------

비베에서 제공하는 배포마법사를 이용해서 일단 셋업파일을 제작합니다.
그럼 해당 소스디렉토리 밑에 \Package 란 폴더가 생성됩니다.
그럼 \Package 폴더에서 폴더 두개를 임의대로 만듭니다.



그런다음, Support 폴더에 들어가 실제 프로그램에서 필요한 파일들만 선택해서
Run 폴더에 복사 또는 이동시킵니다.







인스톨팩토리에서 설치시 설치로고를 사용하고자 하시면 그림판등을 이용하셔서 먼저 작업해 두십시요.
비트 맵은 128X256 크기의 것이 좋으며, 사용하는 색상의 수에는 제한이 없으나 가능하면 Windows 기본색을 가지고 있는 8BPP(256색) 이하의 비트맵을 사용하시는게 좋습니다.
인스톨팩토리를 실행합니다. 상단에 만들기 버튼을 눌러 프로젝트이름을 만듭니다.
그리고 일반탭에서 아래와 같이 설정합니다.

주의해서 보실 부분은 소스폴더,기본설치폴더,설치화일이 만들어질 폴더부분입니다.
간혹 소스폴더라고 되어있어서 비베소스파일들이 있는 디렉토리로 착각을 많이 하시는데,
그 의미가 아니고 설치되면 해당 프로그램폴더에 들어가야 할 파일들만 모아놓은 폴더를 의미합니다.
아까 Run 이라고 지정한 폴더가 해당합니다.
그리고 아까 Setup 이라고 만든 폴더는 설치화일이 만들어질 폴더부분에 지정하시면 됩니다.



두번째 창탭으로 이동하여 아래와 같이 설정합니다.
비트맵은 아까 만드신 설치로고그림을 지정하시면 되고, 지정하지 않으면
인스톨팩토리 디폴트그림이 들어갑니다.
머리글과 꼬리글은 님이 원하시는대로 설정하시면 됩니다.
일반적으로 머리글 48 , 꼬리글 14 정도가 적당합니다.




정보탭메뉴 부분입니다. 설치전 라이센스동의가 필요한 내용을 보여줄 필요가 있거나,
설치 시 보여줘야 할 내용이 있을 때 지정하시면 됩니다.
미리 만들어두지 않았어도 이 화면에서 직접 파일을 생성해서 저장하실 수 있습니다.




단축아이콘탭 부분입니다.
프로그램그룹이름을 먼저 정하십시요. 그룹이름은 시작-프로그램-옆에 나올 이름입니다.






설치 위치를 {ProgramMenu} 로 설정하시면 안되시구요, {ProgramGroup} 로
하셔야 시작-프로그램-내프로그램-안에 단축아이콘이 등록됩니다.

설치 위치를 {StartMenu} 로 지정하시면 시작버튼을 눌렀을 때 나옵니다.
알집설치하면 나오는 실행아이콘을 떠올리시면 이해가 쉬울 듯 하네요.


제거탭 부분입니다.




실행 탭 메뉴부분입니다. (거의 사용안함) 

INI 화일 탭 메뉴부분입니다. (일반적으로 거의 사용안함)
"INI" 탭은 설치시 타겟 시스템의 시스템 INI화일, 또는 새로운 사용자 INI화일을 만들거나
INI섹션, INI키, INI값 등을 기록할 때 쓰입니다.     설치시 InstallFactory가 새로 만든
INI화일이나 기록한 INI섹션, INI키, INI값 등은 특별히 지정하지 않으면 제거시 모두 삭제됩니다.

또, 제거시, INI키를 삭제한 후, 대상 INI섹션이 어떠한 INI키도 가지고 있지 않으면
대상 INI섹션은 삭제되며, INI섹션을 삭제한 후, 대상 INI화일이 어떠한 INI섹션도 가지고
있지 않으면 대상 INI화일은 삭제됩니다.




<화일> 입력창
만들거나 기록할 정보의 INI화일 이름을 입력하는 창입니다.
설치시 이 이름의 화일이 존재하지 않으면 이 이름의 화일을 새로 만듭니다.
화일의 이름에는 폴더 예약어, 상대경로, 절대경로를 사용할 수 있으며,
화일 이름이나 상대경로로 지정하신 경우에는
어플리케이션이나 프로그램이 설치된 폴더가 기본 경로가 되며
필요하면 새로운 폴더를 만듭니다. 화일의 이름에는 다음의 폴더 예약어나 화일 예약어를 사용하실 수 있습니다.

INI화일 이름에 사용할 수 있는 폴더 예약어 또는 화일 예약어

{WinIni}
타겟 시스템의 Windows 디렉토리에 있는 WIN.INI화일이 대상 INI화일이 됩니다.
{WinDrive}
타겟 시스템의 윈도우즈가 설치된 드라이브로 확장됩니다.
{WinDir}
타겟 시스템의 윈도우즈 디렉토리로 확장됩니다.
{WinSysDir}
타겟 시스템의 윈도우즈 시스템 디렉토리로 확장됩니다.
{ProgramFiles}
타겟 시스템의 "Program Files" 폴더가 있는 절대경로로 확장됩니다.
{CommonFiles}
타겟 시스템의 "Common Files" 폴더가 있는 절대경로로 확장됩니다.
{InstallDrive}
어플리케이션이나 프로그램이 설치된 드라이브로 확장됩니다.
{InstallDir}
어플리케이션이나 프로그램이 설치된 디렉토리로 확장됩니다.
{InstallFileDrive}
설치화일이 있는 드라이브로 확장됩니다.
{InstallFileDir}
설치화일이 있는 디렉토리로 확장됩니다.
{TempDir}
타겟 시스템의 임시 디렉토리로 확장됩니다.
위의 예약어는 창의 오른쪽에 있는 화살표를 눌러 선택해서 입력할 수도 있습니다.

<섹션> 입력창
만들거나 기록할 INI항목의 섹션의 이름을 지정하는 창입니다.

<키> 입력창
만들거나 기록할 INI항목의 키의 이름을 지정하는 창입니다.

<값> 입력창기록할 INI항목의 값을 지정하는 창입니다.
기록할 INI 값에는 다음의 폴더 예약어가 사용될 수 있습니다.

INI 값에 사용할 수 있는 폴더 예약어

{WinDrive}
타겟 시스템의 윈도우즈가 설치된 드라이브로 확장됩니다.
{WinDir}
타겟 시스템의 윈도우즈 디렉토리로 확장됩니다.
{WinSysDir}
타겟 시스템의 윈도우즈 시스템 디렉토리로 확장됩니다.
{ProgramFiles}
타겟 시스템의 "Program Files" 폴더가 있는 절대경로로 확장됩니다.
{CommonFiles}
타겟 시스템의 "Common Files" 폴더가 있는 절대경로로 확장됩니다.
{InstallDrive}
어플리케이션이나 프로그램이 설치된 드라이브로 확장됩니다.
{InstallDir}
어플리케이션이나 프로그램이 설치된 디렉토리로 확장됩니다.
{InstallFileDrive}
설치화일이 있는 드라이브로 확장됩니다.
{InstallFileDir}
설치화일이 있는 디렉토리로 확장됩니다.
{TempDir}
타겟 시스템의 임시 디렉토리로 확장됩니다.
{InstallDate}
설치할 때의 날짜가 YYYY-MM-DD 형태로 기록됩니다.
위의 예약어는 창의 오른쪽에 있는 "<"를>
<설치시 이미 설정된 값이 있으면 이 값은 기록하지 않음> 체크박스InstallFactory는 설치시 타겟 시스템에 이미 만들 INI화일 있고,
기록할 정보의 섹션, 키에 값이 이미 설정되어 있어도 새로 설치할 값을 겹쳐 쓰지만
이 체크박스로 겹쳐 쓰지 않도록 지정하실 수 있습니다.
※
InstallFactory는, 키만 존재하고 키의 값이 공백(Blank)인 키는 기록된 정보가 없는 키로 취급합니다.

<제거시 이 값은 삭제하지 않음> 체크박스InstallFactory는 설치시 타겟 시스템에 새로 만든 INI화일, INI섹션, INI키, 기록하거나 겹쳐 쓴 값은
제거시 모두 삭제하지만 이 체크박스로 삭제하지 않도록 지정하실 수 있습니다.

레지스트리 탭 부분입니다. 프로그램이 윈도우시작시 자동시작할 필요가 있거나 하는 경우
해당 레지스트리에 지정을 하는 곳입니다.

<루트 키> 콤보박스만들 서브 키 또는 기록할 레지스트리 정보의 루트 키를 선택할 수 있는 콤보박스로,
HKEY_CLASSES_ROOT,    
HKEY_CURRENT_USER,
HKEY_LOCAL_MACHINE,
HKEY_USERS 중 하나를 선택할 수 있습니다.

<서브 키> 입력창
만들 서브 키 또는 기록할 레지스트리 정보의 서브 키를 입력하는 창입니다.

<값의 이름> 입력창기록할 레지스트리 정보의 키 이름을 지정하는 창입니다.
이 항목을 지정하지 않으시면 기본값을 설정합니다.



DLL 기타 화일 탭 메뉴부분입니다.


아까 비베배포마법사로 생성한 Package\Support 디렉토리안에
있는 DLL 과 OCX 를 추가하시면 됩니다.

StdOle2.tlb설치 폴더: {WinSysDir}
설치시 화일이 이미 있으면: 설치할 화일이 신 버전이면 겹쳐쓰기
제거시: 그냥 두기
(공유 화일: 예)
TypeLib 등록: 예


MSVBVM60.dll설치 폴더: {WinSysDir}
설치시 화일이 이미 있으면: 설치할 화일이 신 버전이면 겹쳐쓰기
제거시: 그냥 두기
(공유 화일: 예)
Server 등록: 예


OleAut32.dll
설치 폴더: {WinSysDir}
설치시 화일이 이미 있으면: 설치할 화일이 신 버전이면 겹쳐쓰기
제거시: 그냥 두기
(공유 화일: 예)
Server 등록: 예


OlePro32.dll설치 폴더: {WinSysDir}
설치시 화일이 이미 있으면: 설치할 화일이 신 버전이면 겹쳐쓰기
제거시: 그냥 두기
(공유 화일: 예)
Server 등록: 예


AsycFilt.dll
설치 폴더: {WinSysDir}
설치시 화일이 이미 있으면: 설치할 화일이 신 버전이면 겹쳐쓰기
제거시: 그냥 두기
(공유 화일: 예)

C:\Windows\System(32)\Ctl3d32.dll
설치 폴더: {WinSysDir}
설치시 화일이 이미 있으면: 설치할 화일이 신 버전이면 겹쳐쓰기
제거시: 그냥 두기
(공유 화일: 예)

ComCat.dll
설치 폴더: {WinSysDir}
설치시 화일이 이미 있으면: 설치할 화일이 신 버전이면 겹쳐쓰기
제거시: 그냥 두기
(공유 화일: 예)
Server 등록: 예

마지막으로, 설치할 어플리케이션이 한글 Visual Basic 어플리케이션일 경우,
VB6KO.DLL을 비롯한, 설치할 어플리케이션이 사용하는 나머지 DLL화일과 OCX화일들을
포함시키시면 됩니다. 이것들만 아무 옵션을 선택하지 않으시면 됩니다.

 
이후 추가된 내용입니다.

일단 패키지 배포 마법사로 설치파일을 만든후 메모장으로 SETUP.LST 파일을 열어 보세요.
[Bootstrap Files] 과 [Setup1 Files] 에 있는 종속파일들을 모두 인스톨 팩토리에서 dll 파일에 추가 합니다.
[Bootstrap Files] 에는 기본적으로 운영체제에 영향을 가지고 있는 중요파일들입니다.
함부로 고치시진 마시구요, 배포판을 제작하는 사양이 윈98이라면 설치할 파일이 신버젼이면  겹쳐쓰기하셔도 무방하지만, 만일 상위버젼 NT/XP 등에서 제작시엔 이렇게 하시면 해당컴퓨터에 문제가 발생합니다.
부득이 상위버젼에서 제작을 해야 하는 상황이시라면 설치할 파일이 있을 경우 설치안함 으로 해두십시요.
대표적으로, Oleaut32.DLL 이 이에 해당하는데 이 파일이 업그레이드되버리면 윈도우98 사용자는 익스플로어 새창뜨기가 안되는 문제가 발생합니다.
그후 (DLLSelfRegister) 라고 된건 서버등록 , (TLBRegister) 라고 된건 타입 등록으로 설정 하시면 됩니다. 
설치 폴더는 시스템 폴더로 하면 됩니다. 
그리고 데이터 베이스를 사용하면 (MSDAOPath) 라는 것이 보일 것입니다. 
이건 자신의 컴퓨터에서 파일 검색을 통하여 해당 파일이 어디에 있는지 확인해 본 후 
그 위치를 지정하시면 됩니다 
예를 들어 DAO360.DLL 파일은  설치위치를 {CommonFiles}\Microsoft Shared\DAO  이렇게 하심 됩니다.
DLL 이나 OCX 등... 이런 종속 파일들은 현재 자신의 컴퓨터에서 존재하는 위치를 참고하여 설정 하면 되더군요.
그리고 설정에서 배포 마법사로 만들었을때 $(Shared) 라고 되어 있다면 이건 공유 파일로 등록한다는 것입니다.
공유 파일이란 다른 프로그램과 함께 해당 종속파일개념으로 사용 하겠다는 뜻이죠.
저는 모든 종속 파일에 공유로 설정을 하였으며 제거시 그냥 놔두기하도록 하였습니다
이렇게 되어 있다면 해당 종속 파일을 서버 등록하며 공유로 한다는 뜻입니다.. 
배포 마법사로 만들었을때 서버 등록을 하라고 되어있는 파일을 서버등록 설정하지 않고 설치파일을 만들면
그 설치 파일로 설치했을때 프로그램이 오류가 나더군요...
배포 마법사로 만든후 그 셋업 리스트의 요구대로 하시기를 추천 합니다..


마지막으로 설치화일 만들기 버튼만 누르면 끝!


----------------------------------------

다시 한번 김재우님께 감사드립니다~ ^^

2013-07-06

PRB: Visual Basic 6을 종료할 때 잘못 된 페이지 오류 모듈 VB6.exe에서 발생.

http://support.microsoft.com/kb/249879/ko

현상
Visual Basic 6.0을 종료 하면 다음 오류 메시지가 나타납니다.
이 프로그램에서 잘못 된 연산을 수행한 및 종료 됩니다.

이 오류 메시지를 표시 하는 대화 상자에서 자세히 클릭 하면 다음과 같은 메시지가 나타납니다.
VB6.exe 
 모듈에서 잘못 된 페이지 오류
.



원인

Visual Basic 프로그램 시작 되었지만 Ssscc.dll에서 시스템 레지스트리를 올바르게 등록 되지 않은 경우 소스 코드 컨트롤 추가 기능을 로드 하려면 구성 되어 있습니다.


해결방법

이 문제를 해결 하려면 다음 두 방법 중 하나를 사용할 수 있습니다.
  • Microsoft Visual SourceSafe Visual Basic 통합 하는 경우:

    시작을 클릭한 다음, 실행을 클릭합니다. 다음 명령 텍스트 상자에 입력 합니다.
    regsvr32 "<x >: \\ssscc.dll "

    여기서 :\ Ssscc.dll 파일의 위치입니다.
  • Microsoft Visual SourceSafe Visual Basic 통합 되어 있지 않은 경우:
    1. Visual Basic 시작 합니다.
    2. 추가 기능 관리자에서 추가 기능 메뉴에서을 클릭합니다
    3. 소스 코드 제어 에서 사용 가능한 추가 기능선택 합니다.
    4. 로드 동작 옵션 상자에서 로드/언로드 및 시작할 때 로드 확인란 선택을 취소 합니다.
    5. Visual Basic 종료하십시오.
추가 정보

소스 코드 제어 Visual SourceSafe Visual Basic 통합합니다.

Windows Mobile 기반 스마트폰에 GPRS 연결이 구성되어 있는지 확인합니다

  1. Visual Basic 및 Visual SourceSafe 설치하십시오.
  2. Ssscc.dll 등록을 취소하십시오.
  3. Visual Basic 응용 프로그램을 시작하고 프로그램을 종료하십시오.
속성

기술 자료: 249879 - 마지막 검토: 2003년 5월 13일 화요일 - 수정: 2.0
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Visual Basic 6.0 Learning Edition 을(를) 다음과 함께 사용했을 때
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
  • Microsoft Visual Basic 6.0 Professional Edition 을(를) 다음과 함께 사용했을 때
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0 을(를) 다음과 함께 사용했을 때
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
키워드: 
kbmt kbprb KB249879 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

2008-10-01

◇ 가상키 값(Virtual Key Values) ◇

글:박후선(OSOLGIL)
osolgil@chollian.net
softech@soback.kornet.nm.kr

OnKeyDown등에서 이용되는 Key값은 VK_* 형태를 지니는 상수로 정의되어 있다.
이 상수들 중 특정 키 값들을 몰라 해메는 경우가 있어 정리해 본다. 자판의 'A'
에서 'Z'까지의 키보드는 VK_A부터 VK_Z까지로 구성되고, 자판의 '0'에서 '9'까
지의 값은 VK_0에서 VK_9와 같다. 이 값들은 문자의 ASCII값과 동일하다. 그 외
나머지 값은 아래와 같다. 이중 VK_Copy등 이용되지 않는 키 값(즉, 키보드로 누
를 수 없는 값)도 있다. 상수의 이름이 그대로 자판의 이름을 나타내므로 별도의
설명은 붙이지 않았다.


VK_LButton = $01; VK_RButton = $02; VK_Cancel = $03;
VK_MButton = $04; VK_Back = $08; VK_Tab = $09;
VK_Clear = $0C; VK_Return = $0D; VK_Shift = $10;
VK_Control = $11; VK_Menu = $12; VK_Pause = $13;
VK_Capital = $14; VK_Escape = $1B; VK_Space = $20;
VK_Prior = $21; VK_Next = $22; VK_End = $23;
VK_Home = $24; VK_Left = $25; VK_Up = $26;
VK_Right = $27; VK_Down = $28; VK_Select = $29;
VK_Print = $2A; VK_Execute = $2B; VK_SnapShot = $2C;
VK_Copy = $2C; VK_Insert = $2D; VK_Delete = $2E;
VK_Help = $2F; VK_NumPad0 = $60; VK_NumPad1 = $61;
VK_NumPad2 = $62; VK_NumPad3 = $63; VK_NumPad4 = $64;
VK_NumPad5 = $65; VK_NumPad6 = $66; VK_NumPad7 = $67;
VK_NumPad8 = $68; VK_NumPad9 = $69; VK_Multiply = $6A;
VK_Add = $6B; VK_Separator = $6C; VK_Subtract = $6D;
VK_Decimal = $6E; VK_Divide = $6F; VK_F1 = $70;
VK_F2 = $71; VK_F3 = $72; VK_F4 = $73;
VK_F5 = $74; VK_F6 = $75; VK_F7 = $76;
VK_F8 = $77; VK_F9 = $78; VK_F10 = $79;
VK_F11 = $7A; VK_F12 = $7B; VK_F13 = $7C;
VK_F14 = $7D; VK_F15 = $7E; VK_F16 = $7F;
VK_F17 = $80; VK_F18 = $81; VK_F19 = $82;
VK_F20 = $83; VK_F21 = $84; VK_F22 = $85;
VK_F23 = $86; VK_F24 = $87; VK_NumLock = $90;
VK_Scroll = $91;

2008-09-01

민성기님의 후킹 강좌(Delphi)

안녕하세요… 민성기 입니다.
화면 키보드를 만들면서 몸에 익힌 훅킹기법~ 남용하면 독이 되지만 잘 만 쓰면 정말 좋은 영약이 되는 것은 세상 다른 이치와 마찬가지겠죠…?? 훅~ 훅훅훅훅~~ (웃음소리 입니다~) 저역시 배우는데 깝깝했던 만큼, 가능하면 쉽게 설명하도록 노력하겠습니다.편의상 존칭은 생략합니다.
이 강좌는 다음과 같은 순서로 진행할 것입니다.
- 훅킹이란 무엇인가- 훅킹의 종류- 훅킹에 사용되는 함수 설명- 훅 프로시저- 훅 프로시저의 위치. 왜 시스템 훅킹은 DLL이어야 하는가.- 실전
{이 글은 Kent Reisdorph가 Delphi Developer's Journal에 기고한 글을 아주 많이 참조하여 작성한 것입니다.}
*** 훅킹이란 무엇인가~누구나 한번쯤, 델파이에 포함되어 있는 스파이 프로그램인 ‘윈 사이트’를 사용해 본 적이 있을 것이다. 이 스파이 프로그램들 처럼, 때때로 윈도우 시스템에서 어떤 일이 일어나고 있는지 알고 싶을 때가 있다. 어떤 어플리케이션이 시작될 때나 끝날 때, 또는 사용자가 쳐대는 마우스의 움직임이나 키보드의 내용 등등… 훅킹이란 윈도우를 괴롭히거나 다른 어플리케이션의 동작을 훔쳐보기 좋아하는 변태적인 프로그래머들을 위해서 윈도우가 마련해 놓은 꽤나 합법적인 통로이다.
이름에서 일 수 있듯이 ‘훅’은 피터팬에 나오는 ‘후크선장’이 오른손에 달고 다니던 엽기적인 갈구리~ 바로 그것이다. 따라서 훅킹은 순 우리말로 하면 ‘갈구리질’ 쯤이 된다. 이 갈구리를 터억~ 하니 메시지가 날아다니는 통로에 찍어놓고 지나가는 메시지를 협박하고 갈취해서 원하는 목적을 이루는 것~ 이것이 훅킹의 모든 것이다. 어떤가~ 듣는 순간, 찌리리~ ‘필’이 오지 않는가~??? ㈜ 물론 표준말은 ‘갈고리’ 입니다만… 왠지 어감이 약해서~ 이 강좌에서는 ‘갈구리’를 쓰겠습니다. 쿄호홋~

*** 훅킹의 종류~갈구리를 찍어두는 위치에 따라 훅은 크게 두가지로 나뉜다. 한 쓰레드만을 집중적으로 괴롭히는 훅킹을 ‘쓰레드 훅킹’, 통 크게 시스템 전체를 상대로 맞짱을 뜨는 훅킹을 ‘시스템 훅킹’이라고 한다. 괴롭히고 싶은 메시지에 따라 갈구리 또한 취사선택 해야 하는데… 이는 머리엔 십자, 배엔 일자 드라이버를 사용해야 하는 일반적인 게임의 법칙과 같다. 즉 윈도우에 관련된 메시지를 상대하기 위해서는 WH_CALLWNDPROC를, 키보드 메시지와 대적하기 위해서는 WH_KEYBOARD라는 갈구리를 사용해야 한다는 말이다. 또한 때와 장소를 잘 가려서 적절한 갈구리를 사용해야 하는데… WH_SYSMSGFILTER같은 무식한 갈구리를 보잘것없는 쓰레드를 상대로 휘두르려 한다면… 큰 형님인 윈도우가 공포의 퍼런화면을 보여주며 ‘고만 밥숟갈 놓지~’ 라며 협박을 하기 때문이다. 자, 이제 우리가 고를 수 있는 갈구리와 타격대상등을 적어둔 취급 설명서를 살펴보자.
**갈구리 취급 설명서* WH_CALLWNDPROC (대상 : 쓰레드 또는 시스템.)윈도우 관련 메시지들이 처리되기 전에 실컷 괴롭힐 수 있는 있는 갈구리.
* WH_CALLWNDPROCRET (대상 : 쓰레드 또는 시스템.)윈도우 관련 메시지들을 처리된 후 실컷 괴롭힐 수 있는 있는 갈구리.
* WH_CBT (대상 : 쓰레드 또는 시스템.)CBT어플리케이션에 대해 사용할 수 있는 놈이라고 하는데…쓰는놈도 잘 모름.
* WH_DEBUG (대상 : 쓰레드 또는 시스템.)다른 갈구리 사용을 디버그할 수 있는 갈구리
* WH_FOREGROUNDIDLE (대상 : 쓰레드 또는 시스템.)어플리케이션의 맨 앞의 윈도우가 아이들 상태일 때 맘껏 때릴 수 있는 갈구리.
* WH_GETMESSAGE (대상 : 쓰레드 또는 시스템.)메시지 큐로 들어오는 메시지들을 괴롭히는 갈구리.
* WH_JOURNALPLAYBACK (대상 : 시스템 만.)저널 레코드 훅에 의해 저장된 키보드나 마우스 이벤트를 재생시킬 수 있는 갈구리. 일반적으로 이 갈구리를 휘두르는 동안은 키보드나 마우스 사용이 정지된다.
* WH_JOURNALRECORD (대상 : 시스템 만.)모든 키보드와 마우스 동작을 괴롭히는 갈구리. 매크로 같은 녀석을 만들 때 아주 유용하다.
* WH_KEYBOARD (대상 : 쓰레드 또는 시스템.)WM_KEYDOWN, WM_KEYUP 메시지 전문 사냥꾼.
* WH_MOUSE (대상 : 쓰레드 또는 시스템.)마우스 메시지 전문 사냥꾼.
* WH_MOUSE_LL (대상 : 쓰레드 또는 시스템.)NT에서만 사용되는 저수준 마우스 갈구리.
* WH_MSGFILTER (대상 : 쓰레드 또는 시스템.)특정 어플리케이션에서 만들어낸 메뉴, 다이얼로그 박스, 스크롤 박스 같은 놈에서 발생하는 메시지를 전문적으로 괴롭힐 수 있는 갈구리.
* WH_SHELL (대상 : 쓰레드 또는 시스템.)윈도우 셀에 관계된 메시지를 전문으로 하는 갈구리.
* WH_SYSMSGFILTER (대상 : 시스템 만.)모든 어플리케이션이 만들어낸 메뉴, 다이얼로그 박스, 스크롤 박스 같은 놈에서 발생하는 메시지를 전문적으로 괴롭힐 수 있는 갈구리.
갈구리질을 잘 하기 위해서는 손에 딱 맞는 갈구리가 필요하다. 위의 취급 설명서가 때와 장소에 따라 적절히~ 갈구리를 선택할 수 있는 지혜에 도움이 되었으면 한다.
*** 윈도우의 훅 함수들~갈구리질을 위해 준비된 윈도우의 API는 세가지 이다. 갈구리를 찍는 녀석인 SetWindowsHookEx, 다 쓴 갈구리를 정리하는 UnHookWindowsHookEx, 마지막으로 단물 다 뽑아먹은 메시지를 기다리고 있는 다음 갈구리에게 넘겨주는 CallNextHookEx가 그것이다. 이 CallNextHookEx를 호출해야 하는 이유는 간단하다. 이미 알고 있겠지만, 윈도우는 나 혼자만 쓰는 것이 아니기 때문이다. 충분히 메시지를 괴롭혔다고 해도, 아직 뒤에는 이 메시지를 노리는 수많은 갈구리들이 있다는 것을 잊지 말자.
** SetWindowsHookEx~위에서도 설명 했지만, 이 함수는 메시지 통로에 갈구리를 찍기 위해 사용되는 녀석이다. 생긴 모양을 보자.
function SetWindowsHookEx( idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD): HHOOK; stdcall;
아~ 정말 흉악하게 생겼다~.
첫번째 인자는 사용할 갈구리의 종류를 의미한다. (취급 설명서를 보자.)두번째 인자는 원하는 메시지가 왔을 때 호출될 ‘훅 프로시저’이다. 훅 프로시저에 대해서는 잠시 후에 살펴보자.세번째 인자는 훅 프로시저가 정의된 DLL이나 EXE의 인스탄스이고 마지막 인자는 괴롭힐 쓰레드의 아이디이다. 시스템 전체를 상대로 갈구리질을 하기 위해서는 이 마지막 인자에 0을, 특정 쓰레드를 괴롭히고 싶으면 원하는 쓰레드의 아이디를 넣어주면 된다. 갈구리가 정확히 찍히면, 이 함수는 훅의 핸들을 넘겨주게 된다. 실패하면 리턴값은 0이다. 이 훅의 핸들은 뒤에 갈구리를 해체할 때나 다음 갈구리를 호출할 때 사용되니 잘 보관해야 한다. 다음 예제는 현재 프로세스에 키보드 훅을 걸어주는 예제이다.
varHKbHook : HHOOK;
...
HKbHook := SetWindowsHookEx(WH_KEYBOARD, MyKBHook, HInstance, GetCurrentThreadId);
갈구리가 괴롭힐 쓰레드의 ID를 얻기 위해 GetCurrentThreadid를 사용했으며 결과값을 HKbHook에 저장해 둔 것에 유의하자.
** UnhookWindowsHookEx~갈구리를 제거하기 위해 사용하는 함수이다. 무사히 뽑히면 True값을, 그렇지 않으면 flase를 리턴한다. 대부분의 경우 갈구리를 뽑을 때 발생하는 에러는, 인자로 넘겨준 훅핸들이 이 함수의 맘에 들지 않을 때 발생한다.
Res := UnhookWindowsHookEx(HKbHook);
예제에서 보듯, 별다른 것이 없는 함수이다. 그저 정확한 훅 핸들을 넘겨주기 위해 훅 핸들 보관에 신경써야 한다는 것을 잊지 말자.
** CallNextHookEx~위에서도 잠깐 언급했지만, 우리가 괴롭히려는 메시지에 한이 맺힌 갈구리는 우리만 있는 것이 아니다. 따라서 적당히 손 본 메시지는 다음 갈구리들에게 넘겨주어야 한다. CallNextHookEx는 다음 갈구리에 메시지를 넘겨주기 위해 사용하는 함수이다. 여러 개의 훅이 ‘체인’으로 연결되어 있다고 이해하면 빠를 것이다.(갈구리에 체인까지~ 랄랄라~~) 실제로 우리가 설치한 훅은 윈도우가 다루는 훅 체인의 하나로서 동작하게 된다. 이 함수의 사용 예는 조금 뒤에 훅 프로시저에서 살펴보도록 하자.
*** 훅 프로시저~갈구리질의 가장 중요한 요소, 아니 갈구리질 그 자체를 뜻하는 녀석이다. (프로시저라고 불리지만, 이건 윈도우가 그렇게 부르기 때문이고~ 파스칼의 입장에서 볼 때는 함수 입니다.) 이 훅 프로시저는 우리가 설정한 훅이 발생할 때, 즉 괴롭히고자 하는 메시지가 발생할 때 호출된다. 키보드 훅을 예로 들면, 사용자가 키보드를 누르거나 뗄 때 실행된다. 윈도우는 갈구리의 형식에 따른 훅 프로시저를 정의해 놓았고, 위에서 언급한 키보드의 경우를 예로 들면 다음과 같다.
function MyKBHook(Code: Integer; wParam: WPARAM; lParam: LPARAM) : LongInt; stdcall;
실은, 나머지 갈구리질 함수 역시 모두 똑같이 생겼다. 다만 갈구리의 형식에 따라 넘어오는 wParam과 lParam이 달라질 뿐이다. 예를 들어, 현재 찍어놓은 갈구리가 WH_CALLWNDPROC 라면 wParam은 발생한 메시지를, lParam에는 메시지가 발생한 핸들 등 기타정보를 담은 구조체에 대한 포인터가 넘어온다. WH_KEYBOARD의 경우는 wParam에 가상 키값이, lParam에 키보드의 상태 등 기타 정보가 넘어오게 된다. 갈구리의 형식에 따른 훅 프로시저에 대해서는 SetWindowsHookEx()에 대한 Win32 API 도움말을 살펴보기 바란다. 이 훅프로시저를 작성할 때는 신경을 많이 써야 한다. 마우스 훅을 예로 들어보자. 설치해 놓은 마우스 훅 프로시저는 마우스 메시지가 발생할 때, 즉 마우스를 움직이기만 하면 호출된다. 만약 머리 터지도록 복잡한 계산을 훅 프로시저 내부에서 한다면… 또는 가뜩이나 느린 화면 그리기 같은 녀석을 여기서 처리 한다면… 뭐 윈도우가 괴롭다 괴롭다 못해 뻗어버릴 지도 모른다. 따라서 적당히~ 괴롭혀야 한다는 말씀~~ ^^; 훅 프로시저에서 메시지를 적당히 타작 했으면, CallNextHookEx()를 통해 다음 갈구리를 불러줘야 한다. 그렇게 하지 않으면 위에서 언급했던 훅체인은 깨져버리고, 메시지는 도망가 버리고 만다. 다음은 아무일도 하지 않는 훅 프로시저의 예이다.
function MyKBHook(Code: Integer; wParam: WPARAM; lParam: LPARAM) : LongInt; stdcall;beginResult := CallNextHookEx( HKbHook, Code, wParam, lParam);end;
CallNextHookEx의 첫번째 인자는 훅의 핸들이다. 나머지 인자들은 훅 프로시저로 넘어온 Code와 wParam, lParam을 채워준다. 또한 이 함수의 결과값을 훅 프로시저의 결과값으로 사용한 것에 주의하자.필자처럼 책상이 좁은 사람들은, 맘 먹고 책 한번 읽으려 해도 키보드가 걸리적 거려 힘이 든다. 이 경우, 시스템 전체에 키보드 훅을 걸어놓고 훅 프로시저에서 CallNextHookEx를 호출하지 않으면 키보드가 동작하지 않게 된다. 키보드에 락을 걸어두는 간단한 유틸리티를 만드는 것도 가능할 것이다.
*** 훅 프로시저의 위치. 왜 시스템 훅킹은 DLL이어야 하는가.~위에서 잠깐 언급 했지만, 훅을 설치할 때, 시스템 전체의 메시지를 괴롭히려면 SetWindowsHookEx의 마지막 인자에 0을, 특정 쓰레드만을 괴롭히려면 괴롭히고자 하는 쓰레드의 ID를 넣어준다.
<쓰레드 훅을 설치하는 예>HKbHook := SetWindowsHookEx( WH_KEYBOARD, MyKBHook, HInstance, GetCurrentThreadId);
<시스템 훅을 설치하는 예>HKbHook := SetWindowsHookEx( WH_KEYBOARD, MyKBHook, HInstance, 0);
쓰레드 훅에서의 훅 프로시저 위치는 별 문제가 되지 않는다. 훅의 핸들 등의 변수가 같은 어플리케이션 영역에 존재하기 때문이다. 그러나 시스템 훅에서는 이것이 큰 문제가 된다. 최초에 훅을 설치할 때는 상관 없지만, (실제로 설치는 된다.) 설치한 훅이 동작하려 할 때 훅 프로시저가 특정 어플리케이션의 영역에 있다면, 메시지가 발생한 어플리케이션에서 이 프로시저에 접근할 방법이 없기 때문이다. 때문에 시스템 훅에서는 훅 프로시저를 DLL에 집어 넣어야 한다. 고민해야 할 문제가 한가지 더 있다. DLL내에 전역변수를 선언해 갈구리를 찍을 때 훅의 핸들을 저장해 두고 훅 프로시저의 CallNextHookEx에서 사용한다고 하자. 이 경우 전역변수에는 어떤 값이 들어가 있을까…?? 최초에 SetWindowsHookEx에서 제아무리 기가막히게 훅의 핸들을 얻어다 넣어주었다 하더라도 각 어플리케이션에서 훅 프로시저가 실행될 때 읽어오게 되는 전역변수의 값은 언제나 0이다. 32비트에서는 각 어플리케이션에서 DLL이 호출될 때, 코드만 공유할 뿐이고 데이터는 각각 다른 프로세스 안에서 ‘보호’되고 있기 때문이다. 따라서 어플리케이션마다 따로 호출될 훅 프로시저에서 정확한 훅의 핸들값을 참조할 수 있도록 데이터 교환 방법에 대해 고민해야 한다.
이경우에 가장 좋은 해결방법은 ‘메모리 맵드 파일 아이오’를 이용하는 것이다. 공유할 파일 맵을 설정해 놓고 훅의 핸들이나 기타 필요한 정보들을 보관하는 것이다. 그러나, 이 개념까지 여기서 설명하기에는 조금 벅찬 듯 싶다. 메모리 맵드 파일 아이오에 대해서는 이 갈구리질 강좌가 끝난 후에 다시한번 고민해 보는 기회를 갖도록 하고, 일단 여기서는 임시적으로 VCL의 파일 스트림을 이용해 하드 디스크에 훅의 핸들을 저장하는 방법을 사용하도록 하겠다.

2006-10-08

R2DJ 1.09

R2DJ 1.09版更新?容
1.角色回程后不??古董商人而直接?去??或?物商店的??已修正.
2.被其他玩家攻????:使用瞬?移??水0秒后自?打怪,
?添加的功能是角色包?里有瞬?移??水?就使用?水,
如果?有瞬?移??水??功?者反方向移?一定距?,
若攻?者??攻?角色?自?反?,要是攻?者停止攻?角色?自?打怪。
3. 被其他玩家攻??警?音不?的??已修正.
4. 在自???列表里添加了速度?水,角色?自???速度?水.
5.全部物品?中?除了"오래된동전",添加了"고블린고리갑옷조각"(갑옷조각),
如果角色已?置了"오래된 동전"存入??,??除。
6.??怪主?攻??角色?先把物品?完后再攻?怪。
// 因外?路?更改,若要使用以前版本的外??置?,?先把原外?路?里的?制,
安?新版本之后,覆盖新版本里的文件。
*角色自???功能(其他玩家?角色??,?自?回?)---??中*用一台??管理多台??的功能(?程管理形式用一台??外?管理多台外?)---??中*??打怪功能(支持1.4)
---??中&???束后立刻添加

2006-02-17

유니코드와 같은 코드의 종류와 그 코드가 쓰이는 방법

1. 아스키 코드(ASCII)
주로 영어와 몇몇 기호를 표시하기 위해 씁니다. 코드값은 0x00 ~ 0x7F사이의 값을 가집니다.

2. ISO-8859-1 부터 ISO-8859-15
주로 유럽에서 쓰이는 언어들(독일어,프랑스어,터키어,그리스어,키릴어(러시아 등) 등등)을
표현하기 위해 쓰입니다. 0x00 ~ 0xFF까지의 값을 가지는데 0x00 ~ 0x7F는 아스키와 동일합니다.

3. 한글 완성형 코드(EUC-KR, UHC)
UHC는 M$ 확장 완성형이라고도 하고, 마이크로소프트사에서 EUC-KR을 기반으로 확장한 것입니다.
0x00 ~ 0x7F의 아스키도 포함합니다.
EUC-KR의 경우 0xA1A1 ~ 0xFEFE값을 가지며, 한글, 한자, 기호 등이 있고, 값에서 알 수 있듯이
2바이트가 하나의 문자를 표현합니다.
UHC는 여기서 첫바이트는 0x81 ~ 0xA0값도 사용하고, 두번째 바이트는 0x41 ~ 0x5A,
0x61 ~ 0x7A, 0x80 ~ 0xA0값도 사용합니다.

4. 한글 조합형 코드(JOHAB)
0x00 ~ 0x7F의 아스키를 포함합니다.
역시 두바이트가 하나의 문자를 표현하는데, 두바이트인 16비트를 가지고 첫비트는 무조건 1,
다음 2 ~ 6 비트가 초성, 7 ~ 11비트가 중성, 12 ~ 16비트가 종성을 나타냅니다.

5. 일본어 EUC-JP 코드
0x00 ~ 0x7F는 아스키
0xA1A1 ~ 0xFEFE는 일본어 글자인 히라가나, 카타카나, 한자, 그리스어, 키릴어 및 각종 기호 영역
0x8EA1 ~ 0x8EFE는 반각 카타카나 영역
0x8FA1A1 ~ 0x8FFEFE는 확장된 그리스어, 키릴어, 한자 등이 있는 영역입니다.
값에서 알 수 있듯이 한 문자를 표현하기 위해 3바이트를 쓰는 경우가 있습니다.

6. 일본어 SHIFT_JIS 코드
0x00 ~ 0x7F는 아스키
정확하게 값이 기억은 안나지만 0x8140부터 시작하는 두바이트로 된 코드들이 있는데
EUC-JP의 0xA1A1 ~ 0xFEFE에 해당하는 문자들이 있습니다.
0xA1 ~ 0xFE는 반각 카타카나 영역입니다.

7. 중국어 GB-2312(간체) 코드
0x00 ~ 0x7F는 아스키
0xA1A1 ~ 0xFEFE 사이에 수많은 한자들과 기호등등의 문자들이 있습니다.

8. 중국어 HZ(간체) 코드
GB-2312를 특정한 방식에 따라 인코딩한 것입니다.

9. 중국어 BIG-5(번체) 코드
0x00 ~ 0x7F는 아스키
두바이트가 한 문자가 되는 코드들이 있는데 이 코드는 변종이 많아서 정확한 값은 모르겠습니다.

10. 중국어 GBK(간체) 코드
마이크로소프트사에서 GB-2312를 기반으로 확장한 코드입니다.

11. 중국어 GB18030 코드
GBK를 포함합니다.
여기다가 한 문자를 표현하기 위해 4바이트까지 확장해서 씁니다.
유니코드에 포함된 모든 문자가 포함되어 있습니다.

12. 한글 ISO-2002-KR
EUC-KR을 특정한 방식에 따라 인코딩한 것입니다.

13. 일본어 ISO-2022-JP/ISO-2022-JP2
EUC-JP와 EUC-KR, GB-2312, ISO-8859-1, ISO-8859-7을 특정한 방식에 따라 인코딩한 것으로
ISO-2022-JP2는 ISO-2022-JP의 확장으로 보시면 됩니다.

14. 중국어 ISO-2022-CN/ISO_2022-CN-EXT
GB-2312, BIG-5에 포함하는 문자 및 기타 다른 여러 중국어 코드들을 특정한 방식에 따라
인코딩한 것입니다.
여기서 알 수 있겠지만 중국어 관련 코드는 위에서 소개한 것 말고도 엄청나게 많습니다.
심지어는 조선족을 위한 (한글) 코드까지 있는 것으로 알고 있습니다.

15. 유니코드
전 세계의 존재했거나, 존재하거나, 앞으로 생길지도 모르는 모든 문자를 지원하기 위해
만들어진 것으로 알고 있습니다. 각종 현대문자, 고대문자, 기호 등등을 포함하며
UTF-32, UTF-16, UTF-8, UTF-7등등의 인코딩 방식에 따라 인코딩되어 사용되고 있습니다.
유니코드에 대한 자세한 설명은 http://www.unicode.org 에서 찾아 읽으시는게 좋을 듯합니다.
물론 국내에도 꽤나 괜찮은 문서들을 검색을 통해 찾아볼 수도 있을 겁니다.

16. 기타 등등
이밖에도 베트남, 인도, 북한의 코드도 따로 있습니다.
베트남은 한자만 있는 코드와 라틴어와 유사한 표기로 되어 있는 코드가 별도로 있는 걸로 알고 있고,
인도는 각 지방마다 글자가 다르기 때문에(음은 같다고 하는 것 같구요..) 표준화된 코드가
나온지 얼마 안된 거로 알고 있습니다. 북한은 한글 완성형 EUC-KR과 거의 유사하게 되어 있고,
특이한 점은 "김일성", "김정일"에 해당하는 6글자의 코드가 특별한 값으로 따로 만들어져 있다는
것입니다.
음.. 별로 도움될 만한 내용은 아니군요...

그밖에도 도스 시절에 도스 환경에서 쓰는거냐, IBM사의 기계에서 쓰는거냐,
맥킨토시에서 쓰는거냐 등등에 따라서도 각각 다른 코드가 있습니다.

아스키 코드, 유니코드 ?

ASCII (American Standard Code for Information Interchange) ; 아스키
아스키는 컴퓨터나 인터넷상에서 텍스트 파일을 위한 가장 일반적인 포맷이다.
아스키 파일에서는 각각의 알파벳이나 숫자 그리고 특수문자들이 7 비트의 2 진수(7개의 0 또는 1의 조합으로 이루어진 스트링)로 표현되며, 총 128개의 문자가 정의되어 있다.
유닉스나 도스 기반의 운영체계(윈도우 NT는 제외)는 텍스트 파일을 표현하는데 있어 아스키를 사용한다.
윈도우 NT의 경우에는 유니코드라고 하는 새로운 코드를 사용하며, IBM의 System 390 서버들은 엡시딕이라고 부르는 자신들만의 고유한 8 비트 코드체계를 사용한다.
따라서 서로 다른 운영체계 간에 어떤 파일을 교환하기 위해서는 코드 변환 프로그램이 필요하게 된다. 아스키는 미국규격협회인 ANSI (American National Standards Institute)에 의해 개발되었다.
영문자, 숫자, 기호를 7비트로 표시하는 미국 표준 코드. ASCII 코드로 표현할 수 있는 문자의 종류는 27=128가지이고, 오류 검사용 패리티 비트 하나를 추가하여 8비트로 2진 코드화함으로써 바이트 단위의 전송이 가능하다.
10여 년 전, 그러니까 16비트 컴퓨터가 보급되기 시작한 시기에 컴퓨터를 처음 배운 사람이라면 ‘아스키’ 코드라는 그리운 단어가 기억에도 생생할 것이다. 아스키(ASCII)는 원래 미국 정보교환 표준 코드(American Standard Code for Information Interchange)로 컴퓨터를 사용하는데 필요한 문자 규약을 말한다. 컴퓨터 환경이 열악하던 그 시절, 흑백 모니터를 들여다보며 자판을 두드리다 지친 사람들은 종종 문자와 기호를 이용해 멋진 그림을 만들어내곤 했다. 따지고 보면 ; ) :-) 8-( T_T 등과 같은 현재의 인터넷 스마일리도 간단하기는 하나 예전에 애용되던 ‘아스키 코드를 이용한 그래픽 표현’과 마찬가지다

유니코드란?
다양한 나라가 서로 동일한 혹은 비슷한 의미의 문자를 저마다 다른 인코딩 방식을 사용함으로써, 자료 및 프로그램의 호환성 및 확장성에 문제를 일으키는 관계로 이를 하나의 문자 세트인 유니코드로 통합시켜 표현함으로써 해결하자는 뜻에서 `유니코드`는 전세계 주요 컴퓨터회사들이 업계표준으로 규정한 만국공통 문자코드로 우리나라에서도 지난 96년 2월16일 서울 롯데호텔에서 설명회를 열었고 우리나라에서도 다양한 서체가 개발되고 있다.
즉 Unicode는 세계 각국의 언어를 통일된 방법으로 표현할 수 있게 제안된 국제적인 코드 규약의 이름을 말한다.
미국에서 개발되어진 컴퓨터는 그 구조가 영어를 바탕으로 정의되어 있기에 26자의 영문 알파벳트와 몇 가지 특수 문자를 표현하기에는 1바이트로 충분하였기 때문에 모든 정보가 1바이트를 단위로 표현되고 있었으나 동양3국의 언어 표현인 한글, 한자 또는 일어 등과 같은 문자는 그 구조가 영어와 달라서 1 바이트로는 표현이 불가능하기에 2바이트로 조합하여 하나의 문자를 표현하는 컴퓨터의 구조적 문제점을 바탕으로 만들어 졌다.
기본적으로 유니코드에서는 16비트를 사용하여 하나의 문자를 표현하고 있다.

2006-02-11

About Game Hacking

원문: Game Hacking : An Overview by Sorin
정리: 이동우(leedw at ssrnet.snu.ac.kr), 2004.8.1

내용
Intro GameHacking이란 무엇인가 필요한 tool은 무엇인가 GameHacking의 유형 DMA란 무엇인가 Code Injection Saved game patching Value poking Memory patching Excutable/Dll patching Techniques 총알, 생명치, 마나등 증감되는 수치를 알고 있는 경우 에너지 바, 총알,
생명치, 마나등 정확한 값을 알 수 없는 경우 Instant Build Hacking Techniques map이 저장되는 방식

1 Intro어렸을 때 한창 오락실에서 죽치고 앉아 있던 시절, 아이들 사이에서는 갤러그나 제비우스에서, 혹은 마계촌같은 게임에서 적의 공격을 받아도 죽지 않는 '무적' 모드가 되는 비법이 회자되곤 했었다. 캐릭터를 특정 위치로 옮겨서 적 캐릭터가 어느 지점에 나타나는 시점에서 무슨 키를 동시에 누르면 무적 모드가 된다는 이야기들이 소곤 거리며 나돌았는데 무적 모드로 플레이를 하면 오락실 아저씨가 와서는 전원을 내려버렸다는 소문이 전설처럼 떠돌았다.
마지막 판은 고사하고 각 레벨의 끝에서 만나는 보스 캐릭터에게 번번히 죽임을 당해서 오락실 기계에 무수히 동전을 갖다 바쳐야 했던 필자같은 아이들에겐 솔깃한 이야기가 아닐 수 없었지만 실제로 무적 모드의 동작이 확인된 것은 없었다.
요즘식으로 말하자면 아마 그것이 게임 프로그램내의 '버그'를 가리키는 것이었을 텐데 그런 버그를 이용하는 것도 일종의 GameHacking의 한 기법이라 할 수 있을 것이다.
이 페이지에서는 바로 GameHacking이 무엇이고 어떻게 이루어지는지에 대한 개략적인 소개를 담게 된다.

2 GameHacking이란 무엇인가필자같이 게임의 끝판까지 클리어하지 못하는 '순발력이 떨어지는' 플레이어가 특정 레벨이나 게임을 클리어하는 방법은 다음의 두 가지중의 하나일 것이다.

게임내에 내장되어 있는 치트 코드(cheat code)를 쓴다. 물론 이것은 게임에서 지원해줘야 한다.
그리고 치트 코드를 쓰게 되면 일반적으로 게임에서 정상적인 플레이어가 아닌 cheater로 간주되기 때문에 고득점이 인정되지 않는등의 제약 사항이 있다.
게임에서 제공하는 치트 코드를 쓰지 않고 툴을 이용해서 게임의 법칙을 바꾼다.
(예를 들어 생명치, 에너지, 총알의 제한을 무제한으로 푸는 것.)
우리가 GameHacking이라고 부르는 것은 2번 방법이다.
주의: 당신이 정말 게임을 좋아한다면 치트 코드는 물론 GameHacking을 통해서 플레이 하는 것은 자제해야 한다. 정상적인 방법으로 게임을 클리어했을 때 게임의 진정한 묘미를 느낄 수 있다.
게임을 모두 클리어하고 난 이후 hacking을 연습하기 바란다.

3 필요한 tool은 무엇인가
Debugger (SoftIce, Olly등) : 메모리에서 실행되고 있는 게임 코드를 추적할 때 쓴다.
Memory Searcher (TSearch, ArtMoney, GameHack, Game Trainer등) : 게임에서 우리가 원하는 값(생명치, 총알, 에너지, 마나, money)이 저장된 주소를 찾아내려 할 때 쓴다.
Hex Editor (HexWorkshop, Hacker's View등) : 게임의 실행 파일(exe)이나 라이브러리(dll), 혹은 게임의 세이브 파일을 편집할 때 쓴다.
Disassembler (W32Dasm) : 게임의 dead-listing을 다룰 때 쓴다. dead-listing이란 메모리이 올려져 있지 않은, 파일로 저장된 게임의 asm 코드를 말한다.
Trainer Maker (Trainer Maker Kit) 혹은 프로그래밍 지식 : 선택 사항이다. trainer를 만들고자 할 때 필요하다.
위의 툴은 http://www.protools.cjb.net/ 이나 http://www.gamehacking.com/ 등 인터넷에서 쉽게 찾을 수 있다.
툴의 캡쳐 하면을 구경하려면 다음을 클릭하라.

4 GameHacking의 유형게임을 hacking하기 위한 방법을 요약하면 다음과 같다.

메모리 해킹(Memory Hacking) : 게임이 차지하고 있는 메모리 영역을 조작하는 기법이다.
1.1 Value poking : 게임에서 제한된 값으로 주어진 생명치, 에너지, mana, 총알 갯수등이 저장된 메모리 값을 변경시키거나 특정 값으로 freezing 하는 것. 1.2 Memory patching : 메모리에 로드된 게임 코드를 변경시키는 기법. 예를 들어 플레이어가 총을 쏠 때 총알을 감소시키는 코드가 다음과 같다고 하자.
어셈 코드 헥사 코드 dec ecx 49 이때 총을 쏴도 총알을 감소시키지 않게 하기 위해선 다음과 같이 instruction을 바꾸면 된다.
어셈 코드 헥사 코드 nop 90 "dec ecx"를 "nop"로 변경시킴으로 해서 총알 갯수는 줄어들지 않을 것이다. 이 방법은 DMA를 다루어야 할 때 가장 효율적인 방법이 된다.

실행파일 해킹(Executable/Dll Hacking) : Memory hacking 기법은 손쉬운 면이 있는 반면, 게임을 exit하고 다시 실행하면 기존에 메모리를 조작했던 것들이 모두 소용이 없게 된다. 실행 파일이나 라이브러리 자체를 조작해야 변경시켰던 값이나 코드가 영구적으로 지속될 수 있다.
2.1 EXE/DLL patching : Memory patching과 동일하나 조작 대상이 메모리가 아닌 파일이며 수정된 사항을 영구적으로 지속시킬 수 있다는 차이가 있다.

세이브 파일 해킹(Saved_Game Hacking)
3.1 .SAVED Patching : 해킹하고자 하는 게임이 "save game" 옵션이 있을 때 세이브 파일을 뒤져서 셋팅 값을 변경시키는 기법이다. 주로 헥사 에디터가 쓰인다.

5 DMA란 무엇인가DMA(Dynamic Memory Allocation)은 게임이 메모리를 다루는 방식의 일종이다. 이름이 의미하는 바와 같이 게임은 어떤 값을 저장하기 위해 메모리를 동적으로 할당하는 경우가 있다. 그것은 게임을 실행할 때마다 어떤 값이 저장되는 메모리 위치가 계속 바뀔 수 있다는 것이다. 예를 들어 어떤 게임에서 총알 갯수, 수류탄 갯수, 생명치를 저장하는 메모리 주소가 다음과 같다고 해보자.
bullets : 100 grenades : 120 life : 150
그런데 게임을 빠져나가서 다시 실행하면 메모리 주소가 다음과 같이 바뀐다.
bullets : 510 grenades : 530 life : 560
그 다음에 게임을 다시 실행하면 또 다음과 같이 바뀐다.
bullets : 610 grenades : 630 life : 660
여기서 무엇을 추론할 수 있는가? 데이타가 저장되는 메모리 주소는 매 실행시마다 바뀐다. 그러나 자세히 보면 3가지 경우 주소값이 100단위로 바뀌며 각 데이타가 저장되는 메모리 주소의 차이는 모두 동일함을 알 수 있다. 즉, 수류탄 갯수는 총알 갯수가 저장된 메모리 주소에서 20번지 다음에 있고 생명치는 수류탄 갯수에서 30번지 다음에 위치해 있는 것이다. DMA 문제는 이렇게 메모리 주소의 패턴pattern을 찾는 것부터 풀어나갈 수 있다. 메모리 주소 할당의 패턴을 알아낸다면 다른 데이타가 저장된 주소값을 쉽게 유추할 수 있다.

6 Code Injection위에서 DMA가 무엇인지 알아 보았다. 그럼 이렇게 매번 메모리 주소가 바뀌는 문제를 어떻게 우회할 수 있을까. 간단하다. 바로 code injection 기법을 이용하면 된다. code injection은 이름이 의미하는 것과 같이 게임에 code를 삽입시키는 것이다. 예를 들어 게임에서 다음과 같은 코드를 찾아냈다고 하자.
mov eax,[ecx] - ecx = 총알 갯수가 저장된 주소를 가리키는 포인터 dec byte ptr [eax] - eax = 총알 갯수가 저장된 주소 mov eax,[ecx+20] - ecx+20 = 수류탄 갯수가 저장된 주소를 가리키는 포인터 dec word ptr [eax] - eax = 수류탄 갯수가 저장된 주소 mov eax,[ecx+50] - ecx+50 = 마나 수치가 저장된 주소를 가리키는 포인터 dec dword ptr [eax] - eax = 마나 수치가 저장된 주소 여기서 처음 ecx에 저장된 주소로 수류탄, 마나 수치까지 알아 낼 수 있으므로 parent address라고 한다. 그런데 이 주소는 DMA로 결정되기 때문에 게임 실행시마다 변경되는 값이다. 그래서 이 ecx 값을 언제든 참고할 수 있도록 특정 장소에 저장해둘 필요가 있다. 특정 장소를 어떻게 찾을까.
게임 코드가 저장된 영역에서 0나 혹은 FF만 채워져 있는 영역을 찾아낸다. 그 부분이 바로 코드에서 쓰이지 않는 영역인데 거기에 우리의 코드를 삽입할 것이다. 코드를 삽입하는 절차는 간단하다.

게임 메모리에서 0이나 FF로 채워져 있는 빈 공간을 찾는다.
게임 코드내에 그 공간으로 "jmp"하거나 "call"하는 코드를 overwrite한다.
overwrite했던 코드 부분을 재구성한다.
나머지 빈 공간에 임의의 코드를 삽입한다. (parent address를 잡아내는 코드)
다시 원래 코드로 jmp back하거나 ret하도록 한다.
위에서 예로 든 코드를 다시 예로 들면,
[ORIGINAL[ [MODIFIED] mov eax,[ecx] jmp 4455 (place full of 0's) dec byte ptr [eax] dec byte ptr [eax] <-------<---------<----<--------- mov eax,[ecx+20] > mov eax,[ecx+20] ^ dec word ptr [eax] dec word ptr [eax] mov eax,[ecx+50] mov eax,[ecx+50] dec dword ptr [eax] dec dword ptr [eax] ^ ................... offset 4455: (원래 0으로 채워져 있던 빈 공간) mov eax,[ecx] - overwrite했던 instruction을 재구성 ^ mov dword ptr[5555],ecx - parent address를 static 영역에 저장 jump back to "dec byte ptr [eax]" ----->--->--->------>------> 이렇게 해서 parent 주소를 static 주소 영역에 저장함으로써 DMA 문제를 해결할 수 있다. trainer에서는 5555번지를 읽어 내서 총알, 수류탄, 생명치등의 수치를 조작할 수 있게 되는 것이다. 예를 들어 trainer에서 총알 갯수를 가져오고자 한다면 다음과 같이 코드를 짜면 된다.
... 5555번지 값을 읽어서 temp에 저장 push temp pop ecx ---> ecx = 총알 갯수가 저장된 주소의 포인터 mov ecx,[ecx] ---> ecx = 총알 갯수가 저장된 주소 mov eax,[ecx] ---> eax = 총알 갯수 (DAM에 관한 sheep의 tut들을 읽어보라.)

7 Saved game patching먼저 .SAVE file patching에 대해서 알아보자. 이는 게임의 세이브 파일을 뒤져서 우리가 원하는 수치가 저장된 데이타를 찾아내서 새로운 수치 값으로 변경시키는 기법을 말한다.
Warcraft2를 예로 들면, single player game을 플레이하다 게임을 저장한다. 이때 보유한 gold 값을 기억해 둔다. 이제 세이브 파일을 HexWorkshop으로 로딩해서 해당 gold 값을 search한다. 이때 search type은 32 Bit Unsigned long 으로 지정한다. 이는 10진수 값으로 찾기 위한 것인데 이 값이 65535 (WORD 타임의 최대값) 보다 크기 때문이다. "value" 에디트 박스에 money 수치를 입력하고 OK를 누르면 된다. 간단하지 않은가?
여기서 원하는 값을 찾기 위해선 세이브를 여러번 시도해야 할 때가 있다. 즉, 마나나 마법 수치등의 값을 찾으려 할 때 상태가 바뀌는 시점에서 게임을 세이브하고 HexWorkshop에서 compare 기능으로 원하는 값을 추적하는 것이다.
그러나 starcraft와 같은 많은 게임들이 세이브시키는 데이타를 암호화(encrytion)하는 경우가 많다. 이 경우에는 세이브 파일을 해킹하는 것보다는 value poking과 같은 게임의 메모리를 해킹하는 것이 더 수월하다.

8 Value poking이 방법은 GameHacking의 가장 일반적인 기법이다. Memory searcher(Tsearch, ArtMoney, 기타 등등)로 특정 수치 값을 검색한다. 물론 이때 같은 값을 가진 주소들이 우후죽순처럼 검색된다. 그럼 게임으로 돌아가서 해당 수치가 바뀌는 동작을 한다. 그리고 다시 memory searcher로 돌아가서 next search로 변경된 수치를 검색한다. 이와 같은 동작을 여러 차례 반복하다 보면 검색되는 주소가 몇 개의 주소로 좁혀지게 된다. 이제 남은 일은 의심되는 주소 값들을 바꾸어 보면서 게임내에서 어떤 영향을 미치는지 알아보는 것이다.
9 Memory patchingDMA, code injection과 함께 쓰이는 경우가 많으며 어셈 지식이 필요하다. 예를 들어 총알의 갯수를 저장하는 주소가 100번지라는 것을 알아냈다고 하자. SoftIce로 100번지에 메모리 브포를 건다. 메모리 브포는 bpm 커맨드를 쓰며 브포 플래그에 읽기(r)나 쓰기(w)를 지정할 수 있다. 이때 주의할 것은 브포를 거는 영역이 게임 모듈 내라는 것을 확인하도록 한다. 소아 화면에서 커맨드 윈도우 오른쪽 하단부에 현재 모듈 네임이 디스플레이 되니 확인하도록 한다.
100번지에 메모리 브포를 걸었으면 게임으로 돌아가서 총을 쏴보자. 그럼 소아 화면이 나타나게 된다.
............. 0001: mov eax, [44] 0002: dec eax ---> 브포는 여기서 걸리게 된다. 0003: mov dword ptr [44], eax ............ 44번지에서 총알의 갯수를 가져와서 총알 갯수를 1 감소시킨다. 그리고 감소된 총알 갯수를 다시 44번지에 저장하는 모습을 볼 수 있다. 따라서 총알 갯수를 감소시키지 않게 하기 위해 "dec eax" 부분에서 단지 nop만 삽입하면 된다. 이것은 SoftIce에서 다음과 같이 입력하면 된다. asm 0002 nop 이렇게 해서 memory patching이 이루어지게 된다.
그러나 매번 게임을 실행할 때마다 SoftIce에서 이런 작업을 할 수는 없는 노릇이다. 이때에는 2가지 방법이 있는데, 첫번째는 trainer를 만들든지 두번째로 게임의 실행 파일이나 라이브러리 자체를 patch하는 것이다.

10 Excutable/Dll patching이 방법은 memory paching과 거의 흡사한 방법이다. 단지 patch된 내용이 영구적으로 지속된다는 점이 다를 뿐이다. 여기서는 위의 총알 갯수를 patch하는 예로 해커의 비장의 무기라 불리는 Hiew를 이용해 보자. Hiew에서 게임의 실행 파일을 로딩한다. F4키를 눌러서 "Decode"를 선택한다. 그리고 F5 (goto address)를 눌러 소아에서 추적했던 총알 갯수를 감소시키는 0002 번지를 입력한다. F3 (Edit)를 누르고 F2 (asm)를 눌러서 "nop" instruction을 입력한다. 그리고 Enter와 ESC를 차례로 누르고 F9 (Save)를 누르면 작업이 모두 끝난다.
주의 : 때론 어떤 게임에서는 생명치나 money등을 감소시키는 instruction이 .exe 내에 없고 .dll에 있는 경우가 있다. 이때는 소아 화면에서 해당 instruction의 offset을 보면 쉽게 알아볼 수 있다. 해당 instruction의 offset이 1XXXXXXX 형태일 때는 현재 dll 안에 있는 instruction이라고 볼 수 있다. 이것은 소아 화면에서 커맨드 윈도우의 오른쪽 하단에 나타나는 모듈 이름에서도 확인할 수 있다.

11 Techniques게임을 해킹하는 여러 테크닉들을 소개하면 다음과 같다.
11.1 총알, 생명치, 마나등 증감되는 수치를 알고 있는 경우
메모리 검색기(memory searcher)로 해당 값을 검색한다.
게임내에서 수치(총알, 생명치, 마나등)가 변경되는 행동을 한다.
메모리 검색기에서 검색한 수치내에서 변경된 값으로 재검색 한다.
검색된 결과 값이 2 - 3개로 좁혀질 때까지 반복한다.
남겨진 주소 값의 내용을 변경시켜 보고 게임에서 어떤 영향을 미치는지 확인한다.

11.2 에너지 바, 총알, 생명치, 마나등 정확한 값을 알 수 없는 경우
메모리를 dump한다.
게임 내에서 수치(총알, 생명치, 마나등)가 변경되는 행동을 한다.
dump한 메모리 중에서 수치가 변경된 주소를 검색한다.
검색된 결과 값이 좁혀질 때까지 반복한다.
남겨진 주소 값의 내용을 변경시켜 보고 게임에서 어떤 영향을 미치는지 확인한다.
참고 : 보통 full로 찬 에너지 바의 수치 값은 250 근방일 경우가 많다.

11.3 Instant Build Hacking Techniques
메모리를 dump한다.
게임 내에서 에너지 수치를 변경시키는 행동을 한다.
dump한 메모리에서 값이 감소된 주소(일반적으로 감소지만 드믈게는 증가되는 게임도 있다.)를 검색한다.
몇 개의 주소로 좁혀질 때가지 반복한다.
남겨진 주소 값의 내용을 변경시켜 보고 게임에서 어떤 영향을 미치는지 확인한다.

11.4 map이 저장되는 방식2D 전략게임인 경우 일반적으로 맵은 matrix 형태로 저장된다.
___________________________ a[1,1] a[1,2] .... a[1,n] a[2,1] a[2,2] .... a[2,n] ...............X......... -> X are your units, and that purple color means u see .....................X... the map in that place a[m,1] a[m,2] .... a[m,n] ----------------------------- 예를 들어 플레이어의 유닛이 a[5, 6]으로 이동한다면, 게임 엔진은 그 장소를 나타내는 matrix를 안개없는 지역(place_without_fog)으로 coded-byte를 집어 넣게 된다. (즉, matrix내에 0은 보이지 않는 지역, 1은 보이는 지역으로 나타낸다면 플레이어의 위치 x 주위를 1로 상태가 바뀌게 된다.) 플레이어의 유닛이 그 장소를 떠난다면 안개 지역(place_with_flog)으로 coded-byte를 삽입한다. (즉, 해당 위치를 나타내는 matrix에 0을 넣게 될 것이다.) 따라서 게임은 다음 2가지의 옵션이 있게 된다.

타이머에 따라 map을 refresh
플레이어의 유닛이 이동함에 따라 map을 refresh
물론 이것은 일반적인 경우이며 게임에 따라 map 상태를 저장하는 방식이 다를 수 있다.
홈