TightVNC portable

2010. 9. 8. 21:13

아는 분이 TightVNC portable을 크랙해 달라고 하셔서.. 잠깐 들여다본 적이 있는데..
정리해 두고자 끄적여 봅니다.

TightVNC portable은 30일간 사용할 수 있는 쉐어웨어 입니다.



Register를 클릭하면 사용자 등록을 할 수 있습니다.



접근할 만한 부분은 다음 2가지 정도일까요.

1) 남은 날짜를 카운팅 하는 루틴.
2) 사용자 등록 처리 루틴.

IDA로 열어서 살펴보면 WinMain에서 다음 부분을 볼 수 있습니다.



CreateWindow를 호출하고 이어서 0xFFFFFEBh(GWL_USERDATA)을 인자로 줘서 SetWindowLong을 호출합니다.
SetWindowLong 특정 윈도우의 속성을 바꿀때 쓰는 함수로 MSDN에 나온 설명입니다

SetWindowLong Function

Changes an attribute of the specified window.
The function also sets the 32-bit (long) value at the specified offset into the extra window memory.

LONG WINAPI SetWindowLong(
 HWND hWnd,
 int nIndex,
 LONG dwNewLong
)


olly 에서 보면 파라미터가 아래와 같이 호출됩니다.

핸들은 앞서 호출한 CreateWindow의 리턴값을, index에 GWL_USERDATA (-21) 을,
마지막 파라미터로 RegisterWindowMessage로 등록한 메시지를 던져줍니다.



GWL_USERDATA에 대한 MSDN의 설명입니다.

GWL_USERDATA(-21) Retrieves the user data associated with the window.
This data is intended for use by the application that created the window. Its value is initially zero.

계속 WinMain을 보면 로컬 변수 주소(dwInitParam)를 ecx와 스택에 넣고 sub_4036D0를 호출.
ecx를 쓰는걸 보니 클래스 멤버 함수 일까요. ecx를 직접 스택에 밀어넣는걸 보니 아리까리 하네요.



sub_4036D0 함수는 ecx주소에 0x200을 더해서 sub_4032A0을 호출.



 sub_4032A0은 인자로 받은 [ecx+200]을 esi에 넣고 (멤버 변수를) 초기화 하는 것 같습니다.



이어서 sub_4033E0을 호출.(dwInitParam을 계속 인자로 물고 갑니다.)



sub_4033E0 은 대충 다음과 같은 기능을 합니다.

1) data와 session 이라는 디렉토리 생성
2) GetFileTime 으로 디렉토리가 생성된 시간을 얻어와서 현재 시스템 시간을 빼고 30 을 더함
3) 이 값이 0 보다 크면  [esi+0x28h]에 1을 집어넣음

마지막에 비교하는 부분 중에 이런 코드가 있네요.



ebx 레지스터에는 두개의 시간을 계산한 결과 값, 즉 처음 실행했으면 0x1E(30) 이라는 값이 들어와
있습니다.
여기에 test 연산을 하면 ZF 만 0이 되고 나머지는 변함이 없습니다.
따라서 setl al 에서 al은 그냥 0이 되고 
ebx는 0xffffffff와 and 연산을 합니다.
결국 eax는 0x1E가 되죠.

hexray로 보니 이렇게 보이네요.


테스트해보니 v8 이 0 보다 작으면 참 이므로 1이, 크면 거짓이므로 0 이 들어갑니다.
부족한 제게는 실로 내공이 느껴지는 한줄입니다.

register 루틴에서도 이 부분의 값 ([esi+40]) 을 확인합니다.
그러므로 등록하지 않고 계속 사용하려면 이 부분의 조건문을 바꿔주는 것만으로 가능합니다.

조금만 더 살펴보자면 WinMain에서는 이어서 DialogBoxParam을 호출합니다.



MSDN에 나온 DiaglogBoxParam의 설명입니다.

DialogBoxParam Function

Creates a modal dialog box from a dialog box template resource.
Before displaying the dialog box, the function passes an application-defined value
to the dialog box procedure as the lParam parameter of the WM_INITDIALOG message.
An application can use this value to initialize dialog box controls.

INT_PTR WINAPI DialogBoxParam(
  __in_opt  HINSTANCE hInstance,
  __in      LPCTSTR lpTemplateName,
  __in_opt  HWND hWndParent,
  __in_opt  DLGPROC lpDialogFunc,
  __in      LPARAM dwInitParam
);

...

dwInitParam [in]
 LPARAM

The value to pass to the dialog box in the lParam parameter of the WM_INITDIALOG message.

마지막 파라미터인 dwInitParam으로 dialog box의 초기화 정보를 전달할 수 있네요.

DialogFunc에 두번째 파라미터가 0x110 (WM_INITDIALOG) 이면 멈추도록 브레이크 포인트를 겁니다.
olly나 immunity에서 쉬프트 + F2를 누르고 [esp+8] == 110h 라고 입력.
그러면 DialogBoxParam의 InitParam으로 넘겨준 값을(0x0012F3EC) SetWindowLong으로 설정하는 것을 볼 수 있습니다.



그리고 해당 컨트롤에 0x111(WM_COMMAND)가 발생하면 GetWindowLong으로 이 주소값을 얻어와서 어쩌고 저쩌고 처리하게 됩니다.

ps. olly, immunity에서 conditional breakpoint 걸 때 && 로 묶어서 조건을 여러 개 할 수 없는건지
제대로 걸리질 않는군요. 자꾸 전에 걸어놓은 구문하고 겹치게 되고-0-



'Reversing' 카테고리의 다른 글

ARM assembly를 공부합시다.  (0) 2011.10.03
Protection ID  (0) 2011.05.11
Vmware detection by vmware I/O port  (0) 2011.04.18
7.7 ddos 바이너리 대충 분석  (2) 2009.08.06
The best text for Reverse Engineering  (0) 2009.06.23
Reversing for Newbies (written by Lena)  (0) 2009.03.27
some instruction  (0) 2009.02.11
bypassing isDebuggerPresent WITHOUT changing mem  (0) 2009.01.28

badcob Reversing