리버스 엔지니어링을 독학으로 얼마나 가능할진 모르겠으나, 최대한 책과 유튜브 등을 보면서 공부를 해보겠다.
시작에 앞서 리버스 엔지니어링에 대해 잠깐 설명하자면 C, C++ 등 고급언어(high level language) 즉 사람이 알아보기 쉽게 만들어진 언어로 개발한 프로그램, 하드웨어등을 IDA, Windbg, Ghidra 등의 도구를 사용하여 분석 후 보다 더 안전하게 만드는 목적이며, 이를 악용하면 인터넷상 존재하는 벽돌판 게임, 인게임 핵등이 만들어진다.
이제 본론으로 들어가면 제목, 제목 하단 내용과 동일하게 정말 어디까지 목표가 될지 모르겠지만 해볼 수 있는 한 계속해서 진행할 스터디다.
exe의 파일의 예상 소스코드
#include <stdio.h>
void main(){
printf("Hello, World\n");
return 0;
}
해당 코드를 리버싱 프로그램으로 돌려보면
해당 창과 같이 나오게 된다.
- 1번 창은 실행파일의 함수를 모아놓는다.
- 2번 창은 함수에 있는 코드를 가지고 와서 보여주는 메인 화면이며 위에 String, Hex view, Structures, Enums, imports, Export 등 프로그램을 쉽고 빠르게 분석할 수 있게 존재하는 것이다.
- 3번 창은 이름 그대로 출력을 하는 동시에 IDC에 입력을 하는 공간이기도 하다.
해당 창에서
text:00000001400010F6 lea rax, aHelloWorld ; "Hello, world!\n"
이 코드 부분에 함수를 들어가 보면
rdata:000000014001A140 aHelloWorld db 'Hello, world!',0Ah,0
로 들어가진다.
문자열(String)로 보면 더 자세히 알 수 있다.
함수 sub_140001000로 들어가서
.text:00000001400010F6 lea rax, aHelloWorld ; "Hello, world!\n"
해당 코드를 조금 더 알아보기 쉽게 단축키 F5를 누르면
int __cdecl main(int argc, const char **argv, const char **envp)
{
Sleep(0x3E8u);
qword_14001DBE0 = (__int64)"Hello, world!\n";
sub_140001060((__int64)"Hello, world!\n");
return 0;
}
위와 같이 나온다.
위 매개변수에서에선 argc, argv, envp로 3개의 인자를 받는다.
- Sleep함수를 호출하여 1초 대기한다.
- qword_14001DBE0에 “Hello, world!\n” 문자열의 주소를 넣은 후
- sub_140001060에 “Hello, world!\n” 를 인자로 전달하여 호출한다.
- 그리고 0을 반환하는 코드의 형태이다.
아래 코드에서 sub_140001060로 클릭을 해보면
아래의 코드로 나온다.
__int64 sub_140001060(__int64 a1, ...)
{
FILE *v1; // rax
va_list va; // [rsp+58h] [rbp+10h] BYREF
va_start(va, a1);
v1 = _acrt_iob_func(1u);
return (unsigned int)sub_140001010(v1, a1, 0i64, (__int64 *)va);
}
va_start는 인자값을 가지고 있기에 void main을 뜻하는거 였고 v1의 부분은 printf 로 생각할 수 있다.
'Security > Reverse Engineering' 카테고리의 다른 글
리버스 엔지니어링, 밑 바닥부터 시작하기 (5) (0) | 2024.04.13 |
---|---|
리버스 엔지니어링, 밑 바닥부터 시작하기 (4) (2) | 2023.11.01 |
리버스 엔지니어링, 밑 바닥부터 시작하기 (3) (2) | 2023.10.28 |
리버스 엔지니어링, 밑 바닥부터 시작하기 (2) (2) | 2023.10.28 |
리버스 엔지니어링, 밑 바닥부터 시작하기 (1) (1) | 2023.10.27 |