728x90
사용자 삽입 이미지
 
GetWindowText()

대부분의 키젠미에 먹히는 핵심 API인 GetWindowText()일 것이다.
이번 글에서는 GetWindowText() 방법을 이용해서 접근을 해보도록 하자
GetWindowText()에 중단점을 건후 이전에 시도했던 것처럼 다시 입력한후에,
"Check the serial" 버튼을 클릭하면 올리디버그가 중단점이 걸린 상태로
아래와 같은 지역의 코드를 보여줄것이다

00401085  |.  6A 66         PUSH 66                                  ; /ControlID = 66 (102.)
00401087  |.  53            PUSH EBX                                 ; |hWnd
00401088  |.  E8 159C0000   CALL <JMP.&USER32.GetDlgItem>            ; \GetDlgItem
0040108D  |.  6A 64         PUSH 64                                  ; /Count = 64 (100.)
0040108F  |.  8D95 48FFFFFF LEA EDX,DWORD PTR SS:[EBP-B8]            ; |
00401095  |.  52            PUSH EDX                                 ; |Buffer
00401096  |.  50            PUSH EAX                                 ; |hWnd
00401097  |.  E8 129C0000   CALL <JMP.&USER32.GetWindowTextA>        ; \GetWindowTextA
0040109C  |.  6A 68         PUSH 68                                  ; /ControlID = 68 (104.)
0040109E  |.  53            PUSH EBX                                 ; |hWnd
0040109F  |.  E8 FE9B0000   CALL <JMP.&USER32.GetDlgItem>            ; \GetDlgItem
004010A4  |.  6A 64         PUSH 64                                  ; /Count = 64 (100.)
004010A6  |.  8D8D E4FEFFFF LEA ECX,DWORD PTR SS:[EBP-11C]           ; |
004010AC  |.  51            PUSH ECX                                 ; |Buffer
004010AD  |.  50            PUSH EAX                                 ; |hWnd
004010AE  |.  E8 FB9B0000   CALL <JMP.&USER32.GetWindowTextA>        ; \GetWindowTextA
004010B3  |.  6A 67         PUSH 67                                  ; /ControlID = 67 (103.)
004010B5  |.  53            PUSH EBX                                 ; |hWnd
004010B6  |.  E8 E79B0000   CALL <JMP.&USER32.GetDlgItem>            ; \GetDlgItem
004010BB  |.  8BF0          MOV ESI,EAX

[F8 로 계속 진행하다보면 시리얼이 나타난다]

대상 키젠미가 Name과 Serial을 읽어오는 부분이라는걸 알수 있다.
여기서 부터 스크롤바를 조금 내리다 보면 아래와 같은 시리얼 생성부를 만날수 있다.

0040110C |> /0FBE840D 48FF>/MOVSX EAX,BYTE PTR SS:[EBP+ECX-B8] //이름을 한글자씩 EAX로 옮김.
00401114 |. |41 |INC ECX //ECX값 1증가
00401115 |. |33C1 |XOR EAX,ECX //EAX와 ECX를 XOR
00401117 |. |03D8 |ADD EBX,EAX //EBX에 EAX값을 더함.
00401119 |. |3B4D D8 |CMP ECX,DWORD PTR SS:[EBP-28] //문자열의 길이와 ECX가 같은가?
0040111C |.^75 EE JNZ SHORT k4n.0040110C //그렇지 않다면 점프
0040111E |. 6BC0 06 IMUL EAX,EAX,6 //EAX값에 0x6을 곱함.
00401121 |. C1E3 07 SHL EBX,7 //왼쪽으로 7번 민다.
00401124 |. 03C3 ADD EAX,EBX //EAX에 EBX값을 더한다.

그리고 그의 조금 밑에서 이 시리얼을 문자열화 시키는 코드와 우리가 입력한
시리얼과 올바른 시리얼이 같은지 비교하는 부분을 볼수 있다.

00401129 |. FF75 C8 PUSH DWORD PTR SS:[EBP-38] ; /Arg3 = 0000C570
0040112C |. 68 38B44000 PUSH k4n.0040B438 ; |Arg2 = 0040B438 ASCII "%lX"
00401131 |. 8D8D 80FEFFFF LEA ECX,DWORD PTR SS:[EBP-180] ; |
00401137 |. 51 PUSH ECX ; |Arg1
00401138 |. E8 873D0000 CALL k4n.00404EC4 ; k4n.00404EC4

사용자 삽입 이미지

0040113D에서 멈추어 있을떄 우리는 "asus"에 대한 올바른 시리얼인 "E1CA"을 볼수 있다.
하지만 우리는 키젠미를 만들기를 원함으로 위에서 알아낸 올바른 시리얼 생성 코드만으로도
충분하다.

시리얼 비교 :
00401140 |. 8D85 80FEFFFF LEA EAX,DWORD PTR SS:[EBP-180]
00401146 |. 50 PUSH EAX ; /String2
00401147 |. 8D95 E4FEFFFF LEA EDX,DWORD PTR SS:[EBP-11C] ; |
0040114D |. 52 PUSH EDX ; |String1
0040114E |. E8 339C0000 CALL ; lstrcmpA
00401153 |. 85C0 TEST EAX,EAX
00401155 |. 75 0D JNZ SHORT k4n.00401164 //문자열이 같지 않으면 점프

 
728x90

'Rev. Engineering > Tutorials' 카테고리의 다른 글

Unpacking Yoda's Protector v.1.03.x.SWF Protect v.1.1  (3) 2008.03.29
Asprotect Unpacking Tip  (0) 2008.02.16
자주쓰이는 Win32 API 함수들  (0) 2008.01.14
Packer Site  (0) 2008.01.11

+ Recent posts