티스토리 뷰
[Reversing] Inline Code Patch
[Reversing] Inline Code Patch ②
원하는 코드를 직접 수정하기 어려운 경우 코드 케이브라고 하는 패치 코드를 삽입한 후 실행해 프로그램을 패치시키는 기법을 인라인 코드(Inline Code Patch)라고 합니다.
흐름을 변경하여 삽입된 코드 영역을 거쳐서 수행되도록 하는 기법을 말합니다.
위 파일을 통해 실습을 할 것입니다.
[프로그램 실행시 팝업창]
- 살펴보니, 텍스트 박스에 unpack me와 같은 문자가 보입니다.
- x64 dbg를 통해 살펴보겠습니다.
1. x64 dbg & 흐름분석
- EntryPoint로 이동을 하겠습니다.
401000 PUSHAD
- PUSHAD를 통해 레지스터의 값을 스택에 저장했습니다.
401001 CALL <UNPACKME#1.AC.SUB_4010E9>
- 4010E9로 따라가도록 하겠습니다.
[EP코드]
4010E9 MOV EAX, UNPACKME#1.AC.4010F5
- 4010F5를 EAX에 저장합니다.
4010EE PUSH EAX
- EAX를 스택에 저장합니다.
4010EF CALL <UNPACKME#1.AC.SUB_40109B>
- 40109B로 따라가도록 하겠습니다.
[4010E9 주소]
40109B PUSH EAX
40109C MOV EBX, EAX
- 함수의 스택 프레임을 생성합니다.
- EBX에 4010F5를 저장합니다
40109E MOV ECX, 154
- ECX에 154를 저장하는데 ECX가 0이 될때까지 아래 루프를 실행할 것 같습니다.
4010A3 XOR BYTE PTR DS:[EBX], 44
4010A6 SUB ECX, 1
4010A9 INC EBX
4010AA CMP ECX, 0
4010AD JNE UNPACKME#1.AC.4010A3
- 복호화 루프에서 ECX를 1씩 감소시키면서 EBX 값을 1씩 증가 시킵니다.
- XOR 연산을 통하여 복호화가 진행된다는걸 확인할수 있습니다.
- ECX가 0이 되면 루프를 벗어나 4010AF 부터 진행됩니다.
[복호화]
[복호화 루프]
4010AF PUSH EAX
- EAX(4010F5)을 스택에 저장합니다.
4010B0 CALL <UNPACKME#1.AC.SUB_4010BD>
- 4010BD로 따라가도록 하겠습니다.
4010BD PUSH EAX
4010BE MOV EBX, UNPACKME#1.AC.401007
- 함수의 스택 프레임을 생성합니다.
- EBX에 401007을 저장합니다
4010C3 MOV ECX, 7F
- 이전과 같이 ECX에 7F를 저장하는데 ECX가 0이 될때까지 아래 루프를 실행할 것 같습니다.
4010C8 XOR BYTE PTR DS:[EBX], 7
4010CB SUB ECX, 1
4010CE INC EBX
4010CF CMP ECX, 0
4010D2 JNE UNPACKME#1.AC.4010C8
- 첫번째 복호화 루프입니다.
- 401007 ~ 401085 영역까지 복호화를 합니다.
4010D4 MOV EBX, EAX
4010D6 MOV ECX,154
4010DB XOR BYTE PTR DS:[EBX], 11
4010DE SUB ECX, 1
4010E1 INC EBX
4010E2 CMP ECX, 0
4010E5 JNE UNPACKME#1.AC.4010DB
- 두번째 복호화 루프입니다.
- 4010F5 ~ 401248 영역까지 복호화를 합니다.
- 해당 영역은 이중으로 암호화가 되어있다는걸 확인할수 있습니다.(40109B 함수)
[복호화]
[복호화 루프]
4010B5 PUSH EAX
- EAX(4010F5)을 스택에 저장합니다.
4010B6 CALL <UNPACKME#1.AC.SUB_401039>
- 401039로 따라가도록 하겠습니다.
401039 PUSH EAX
40103A MOV EBX, EAX
- 함수의 스택 프레임을 생성합니다.
- EBX에 4010F5를 저장합니다
40103C MOV ECX, 154
- ECX에 154를 저장합니다.
401041 MOV EDX, 0
- EDX 값을 0으로 만듭니다.
401046 ADD EDX, DWORD PTR DS:[EBX]
- 4byte 단위로 값을 읽어온 뒤 ADD 연산을 실행합니다.
401048 SUB ECX, 1
40104B INC EBX
40104C CMP ECX, 0
40104F JNE UNPACKME#1.AC.401046
401062 CMP EDX, 31EB8DB0
401062 CMP EDX, 31EB8DB0
- EDX(CRC 체크섬) 값과 31EB8DB0을 비교합니다.
401068 JE UNPACKME#1.AC.401083
- 31EB8DB0과 같으면 JE로 인해 401083 주소로 점프합니다.
40106A PUSH 30
40106C PUSH UNPACKME#1.AC.401032
401071 PUSH UNPACKME#1.AC.401009
401076 PUSH 0
401078 CALL <JMP .&MessageBoxA>
40107D PUSH EAX
40107E CALL <JMZ .&ExitProcess>
- 서로 다른 값일 경우 아래와 같은 "Error" 알림창을 띄우게 됩니다.
401083 JMP UNPACKME#1.AC.40121E
- 40121E로 점프해보겠습니다.
OEP(Original Entry Point)
40121E PUSH 0
401220 CALL <JMP. &GetModuleHandleA>
401225 MOV DWORD PTR DS:[403018], EAX
40122A PUSH 0
40122C PUSH UNPACKME#1.AC.4010F5
- DLGPROC lpDialogFunc
401231 PUSH 0
- HWWD hWndParent
401233 PUSH UNPACKME#1.AC.403024
- LPCTSTR lpTemplate
401238 PUSH DWORD PTR DS:[403018]
- HINSTANCE hInstance
40123E CALL <JMP .&DialogBoxParamA>
- 다이얼로그 중 lpDialogFunc는 다이얼로그 박스 프로시저 주소를 가르킵니다.
401243 PUSH EAX
401244 CALL <JMP .&ExitProcess>
- GetModuleHandleA, DialogBoxParamA, ExitProcess 3개의 API 함수를 호출했습니다.
- 스택에 역순으로 40122C 주소가 lpDialogFunc의 4010F5 값 입니다.
- 위 40122C(lpDialogFunc) 통하여 문자열을 띄우게 되는걸 알아냈고, 코드 케이브를 이용하여 패치를 해보겠습니다.
'Reversing > Reversing Tech' 카테고리의 다른 글
[Reversing] Process Hollowing 기법 (0) | 2019.07.25 |
---|---|
[Reversing] Inline Code Patch ② (0) | 2019.07.19 |
[Reversing] PE 파일 만들기④ (0) | 2019.06.25 |
[Reversing] PE 파일 만들기③ (0) | 2019.06.25 |
[Reversing] PE 파일 만들기② (0) | 2019.06.17 |
- Total
- Today