728x90
Packer를 배우기 위한 과정
• VM을 공부하기 전에 OPCODE를 잘 다루어야 한다
수행할 연산자를 표시하는 것이 OPCODE (Operation Code) 라고 한다. 이는 "함수 연산", "자료 전달", "제어", "입출력" 으로 세분화 된다.
- Hello-SDEV를 출력하는 C코드를 작성 후 어셈블리어로 변환하여 살펴보고 똑같이 작성하라
#include <stdio.h>
int main()
{
printf("Hello S-DEV");
}
#include <stdio.h>
char message[] = "Hello S-DEV";
char format[] = "%s\n";
int main()
{
__asm
{
// message 주소를 eax에 레지스터에 로드한다.
lea eax, message
// 스택에 푸시
push eax
// 형식 문자열을 스택에 푸시
lea eax, format
push eax
// printf 함수 호출
call printf
// 스택 정리
add esp, 8
}
}
- 두 숫자의 합을 계산하는 함수를 작성 후, 어셈블리어로 변환하여 살펴보고 똑같이 작성하라
#include <stdio.h>
int a = 5;
int b = 10;
char format[] = "result : %d\n";
int main()
{
__asm
{
mov eax, [a]
mov edx, [b]
add eax, edx
push eax
lea eax, format
push eax
call printf
add esp, 8
}
}
- 컴퓨터와 가위바위보를 진행하는 함수를 작성 후, 어셈블리어로 변환하여 살펴보고 똑같이 작성하라
> 디버그 했을 때
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
0081199F add byte ptr [ebx],dh
008119A1 lds ecx,fword ptr [ecx+10B9FC45h]
008119A7 rol byte ptr [ecx-6661800h],0FFh
008119AE jmp fword ptr [edx]
// 시드 값 설정을 위해 시간을 사용
srand(time(NULL));
008119B1 call time (0811D00h)
008119B6 add esp,4
008119B9 mov esi,esp
008119BB push eax
008119BC call dword ptr [__imp__srand (081B178h)]
008119C2 add esp,4
008119C5 cmp esi,esp
008119C7 call __RTC_CheckEsp (0811267h)
printf("가위(1), 바위(2), 보(3) 중 하나를 선택하세요: ");
008119CC push offset string "\xb0\xa1\xc0\xa7(1), \xb9\xd9\xc0\xa7(2), \xba\xb8(3) \xc1\xdf \xc7\xcf\xb3\xaa@"... (0817B30h)
008119D1 call _printf (08110DCh)
008119D6 add esp,4
int userChoice;
scanf("%d", &userChoice);
008119D9 lea eax,[userChoice]
008119DC push eax
008119DD push offset string "%d" (0817B68h)
008119E2 call _scanf (0811037h)
008119E7 add esp,8
if (userChoice < 1 || userChoice > 3) {
008119EA cmp dword ptr [userChoice],1
008119EE jl __$EncStackInitStart+6Ah (08119F6h)
008119F0 cmp dword ptr [userChoice],3
008119F4 jle __$EncStackInitStart+81h (0811A0Dh)
printf("잘못된 입력입니다. 가위(1), 바위(2), 보(3) 중에서 선택하세요.\n");
008119F6 push offset string "\xc0\xdf\xb8\xf8\xb5\xc8 \xc0\xd4\xb7\xc2\xc0\xd4\xb4\xcf\xb4\xd9. \xb0\xa1\xc0\xa7(1), \xb9\xd9\xc0@"... (0817B6Ch)
008119FB call _printf (08110DCh)
00811A00 add esp,4
return 1; // 프로그램 종료
00811A03 mov eax,1
00811A08 jmp __$EncStackInitStart+17Fh (0811B0Bh)
}
// 1: 가위, 2: 바위, 3: 보
int computerChoice = rand() % 3 + 1; div idiv -> add + 1
00811A0D mov esi,esp
00811A0F call dword ptr [__imp__rand (081B174h)]
00811A15 cmp esi,esp
00811A17 call __RTC_CheckEsp (0811267h) 내부적으로 esp가 정리가 되었는지 확인
00811A1C cdq
00811A1D mov ecx,3
00811A22 idiv eax,ecx
00811A24 add edx,1
00811A27 mov dword ptr [computerChoice],edx
printf("컴퓨터의 선택: ");
00811A2A push offset string "\xc4\xc4\xc7\xbb\xc5\xcd\xc0\xc7 \xbc\xb1\xc5\xc3: " (0817BB8h)
00811A2F call _printf (08110DCh)
00811A34 add esp,4
if (computerChoice == 1) {
00811A37 cmp dword ptr [computerChoice],1
00811A3B jne __$EncStackInitStart+0C0h (0811A4Ch)
printf("가위\n");
00811A3D push offset string "\xb0\xa1\xc0\xa7\n" (0817BCCh)
00811A42 call _printf (08110DCh)
00811A47 add esp,4
}
00811A4A jmp __$EncStackInitStart+0E2h (0811A6Eh)
else if (computerChoice == 2) {
00811A4C cmp dword ptr [computerChoice],2
00811A50 jne __$EncStackInitStart+0D5h (0811A61h)
printf("바위\n");
00811A52 push offset string "\xb9\xd9\xc0\xa7\n" (0817BD4h)
00811A57 call _printf (08110DCh)
00811A5C add esp,4
}
00811A5F jmp __$EncStackInitStart+0E2h (0811A6Eh)
else {
printf("보\n");
00811A61 push offset string "\xba\xb8\n" (0817BDCh)
00811A66 call _printf (08110DCh)
00811A6B add esp,4
}
printf("당신의 선택: ");
00811A6E push offset string "\xb4\xe7\xbd\xc5\xc0\xc7 \xbc\xb1\xc5\xc3: " (0817BE0h)
00811A73 call _printf (08110DCh)
00811A78 add esp,4
if (userChoice == 1) {
00811A7B cmp dword ptr [userChoice],1
00811A7F jne __$EncStackInitStart+104h (0811A90h)
printf("가위\n");
00811A81 push offset string "\xb0\xa1\xc0\xa7\n" (0817BCCh)
00811A86 call _printf (08110DCh)
00811A8B add esp,4
}
00811A8E jmp __$EncStackInitStart+126h (0811AB2h)
else if (userChoice == 2) {
00811A90 cmp dword ptr [userChoice],2
00811A94 jne __$EncStackInitStart+119h (0811AA5h)
printf("바위\n");
00811A96 push offset string "\xb9\xd9\xc0\xa7\n" (0817BD4h)
00811A9B call _printf (08110DCh)
00811AA0 add esp,4
}
00811AA3 jmp __$EncStackInitStart+126h (0811AB2h)
else {
printf("보\n");
00811AA5 push offset string "\xba\xb8\n" (0817BDCh)
00811AAA call _printf (08110DCh)
00811AAF add esp,4
}
// 결과 결정
if (userChoice == computerChoice) {
00811AB2 mov eax,dword ptr [userChoice]
00811AB5 cmp eax,dword ptr [computerChoice]
00811AB8 jne __$EncStackInitStart+13Dh (0811AC9h)
printf("비겼습니다!\n");
00811ABA push offset string "\xba\xf1\xb0\xe5\xbd\xc0\xb4\xcf\xb4\xd9!\n" (0817BF0h)
00811ABF call _printf (08110DCh)
00811AC4 add esp,4
}
00811AC7 jmp __$EncStackInitStart+17Dh (0811B09h)
else if ((userChoice == 1 && computerChoice == 3) ||
(userChoice == 2 && computerChoice == 1) ||
00811AC9 cmp dword ptr [userChoice],1
00811ACD jne __$EncStackInitStart+149h (0811AD5h)
00811ACF cmp dword ptr [computerChoice],3
00811AD3 je __$EncStackInitStart+161h (0811AEDh)
00811AD5 cmp dword ptr [userChoice],2
00811AD9 jne __$EncStackInitStart+155h (0811AE1h)
00811ADB cmp dword ptr [computerChoice],1
00811ADF je __$EncStackInitStart+161h (0811AEDh)
00811AE1 cmp dword ptr [userChoice],3
00811AE5 jne __$EncStackInitStart+170h (0811AFCh)
00811AE7 cmp dword ptr [computerChoice],2
00811AEB jne __$EncStackInitStart+170h (0811AFCh)
(userChoice == 3 && computerChoice == 2)) {
printf("당신이 이겼습니다!\n");
00811AED push offset string "\xb4\xe7\xbd\xc5\xc0\xcc \xc0\xcc\xb0\xe5\xbd\xc0\xb4\xcf\xb4\xd9!\n" (0817C00h)
00811AF2 call _printf (08110DCh)
00811AF7 add esp,4
}
00811AFA jmp __$EncStackInitStart+17Dh (0811B09h)
else {
printf("컴퓨터가 이겼습니다!\n");
00811AFC push offset string "\xc4\xc4\xc7\xbb\xc5\xcd\xb0\xa1 \xc0\xcc\xb0\xe5\xbd\xc0\xb4\xcf\xb4\xd9!\n" (0817C18h)
00811B01 call _printf (08110DCh)
00811B06 add esp,4
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char message[] = "가위(1), 바위(2), 보(3) 중 하나 선택";
char format[] = "%s\n";
int userChoice;
char format1[] = "%d";
int computer = 0;
//
char dr[] = "비겼습니다.";
char wi[] = "이겼습니다.";
char lo[] = "졌습니다.";
char formatd[] = "%d\n";
int main()
{
srand(time(NULL));
/* printf("%p\n", temp);
__asm {
lea eax, temp
push eax
call printf
add esp,4
}*/
__asm
{
// 가위 바위 보 선택
lea eax, message
push eax
lea eax, format
push eax
call printf
add esp, 8
// 사용자 입력 값
lea eax,[userChoice]
push eax
lea eax, format1
push eax
call scanf
add esp, 8
// 컴퓨터 값
// rand()%3+1
mov esi, esp
call rand // - > return eax
//mov edx, 0x1 // edx require 0 -> cdq 다른 방법으로는 xor edx, edx 로 사용할 수 있음
cdq
mov ecx, 0x3
// idiv를 하면 eax에는 몫에 저장, edx에는 나머지 값이 저장
idiv ecx
add edx, 1
mov dword ptr[computer], edx
push edx
push offset formatd
call dword ptr printf
add esp, 8
// 결과 값 출력
mov eax, dword ptr[userChoice]
cmp eax, dword ptr[computer]
// 값이 같을 경우
je Draw
// 첫 번째 조건 (userChoice == 1 && computer == 3)
cmp dword ptr[userChoice], 1
jne First
cmp dword ptr[computer], 3
jne First
je Win
// 두 번째 조건 (userChoice == 2 && computer == 1)
First:
cmp dword ptr[userChoice], 2
jne Second
cmp dword ptr[computer], 1
jne Lose
je Win
// 세 번째 조건 (userChoice == 3 && computer == 2
Second:
cmp dword ptr[userChoice], 3
jne Lose
cmp dword ptr[computer], 2
jne Lose
je Win
Draw:
push offset dr
call printf
add esp, 4
jmp end
Win:
//mov eax, wi
push offset wi
call printf
add esp, 4
jmp end
Lose:
//mov eax, lo
push offset lo
call printf
add esp, 4
jmp end
end:
}
}
'S-DEV > 패커 제작' 카테고리의 다른 글
Tiny Encryption Algorithm (0) | 2023.08.31 |
---|---|
codeengn (0) | 2023.08.24 |