프로그램이 시작되면 EP(Enty Point)코드에서 처음 하는 일은 VB 엔진의 메인 함수(ThunRTMain)를 호출하는 것입니다

EP 주소는 401238 입니다
401238 주소의 PUSH 401E14 명령에 의해 RT_MainStruct 구조체 주소(401E14)를 스택에 입력합니다
그리고 40123D 주소의 CALL 명령에 의해서 JMP 명령이 실행됩니다
이 JMP 명령으로 인해서 VB 엔진의 메인 함수인 ThunRTMain() 함수로 갑니다
1. 간접 호출
40123D 주소의 CALL 401232 명령은 ThunRTMain() 함수 호출
MSVBVM60.dll!ThunRTMain()으로 직접 가는 것이 아닌 중간의 401232 주소의 JMP 명령을 통해서 가는 방식입니다
이러한 기법을 간접 호출 기법이라고 합니다
2. RT_MainStruct 구조체
ThunRTMain() 함수의 파라미터인 RT_MainStruct 구조체를 주목해야 합니다
401E14 주소에 RT_MainStruct가 존재합니다

RT_MainStruct 구조체의 멤버는 또 다른 구조체의 주소들입니다
VB엔진은 파라미터로 넘어온 RT_MainStruct 구조체를 가지고 프로그램의 실행에 필요한 모든 정보를 얻는 다는 것을 알 수 있습니다
3. crackme 분석
먼저 abex' crackme#2를 실행시켰습니다

창이 하나 나타납니다
여기서 이름과 시리얼을 무작위로 작성 후에 Check 버튼을 클릭했습니다

틀렸다는 메시지 박스가 출력됩니다
이제 디버거에서 패치를 위한 코드가 어디에 존재해야 하는지 찾아봅니다
먼저 문자열 검색 기능을 활용하여 방금 확인한 메시지 박스의 문자열을 확인할 수 있습니다

Wrong Serial 문자열이 존재하는 주소인 403458로 이동해봤습니다

위로 조금 올려보다보면 조건 분기문을 확인할 수 있습니다

403329 주소의 _vbaVarTstEq() 함수를 호출 한 뒤 리턴 값(AX)을 비교(TEST 명령)한 후 403332 주소의 조건 분기(JE 명령)에 의해서 참, 거짓 코드로 분기하게 됩니다
403329 주소의 _vbaVarTstEq() 함수가 문자열 비교 함수(예를들어 strcmp)라면 그 위에 있는 두개의 PUSH는 비교 함수의 파라미터, 즉 비교 문자열이 될 것입니다
403329 주소까지 디버깅을 진행했습니다


스택에서 EBP를 기준으로 정렬하면 우리가 입력한 값들을 확인할 수 있습니다
해당 주소는 006C7334에 이름을 입력하였고 006C782C에 시리얼 번호를 입력했습니다
시리얼 번호와 비교하는 문장이 존재할 것입니다
해당 값은 B6C9DAC9와 비교하는 문장이 실행됩니다
EDX에는 시리얼 번호가 입력되며 EAX에는 입력한 시리얼 값이 입력되어 서로 비교하는 TEST 명령을 실행하게 됩니다
시리얼 번호로 B6C9DAC9를 입력했습니다
