Tuesday, August 2, 2011

Programming of Asterisk Viewer

Author:qqaben
I download a software of Asterisk Viewer these two days,Software has ugly windows And farraginous performance,Let me not inthe mood to use, So I writed myself.I know to send WM_GETTEXT event for get window's text,do it:

code:
//控制台
    ..........
    while(1)
    {
      Sleep(1000);
      POINT Point;
      ::GetCursorPos(&Point);
      HWND m_hWnd=WindowFromPoint(Point);
      if(m_hWnd)
      {
        char szText[256];
        int iLength = SendMessage(m_hWnd,WM_GETTEXT,256,(LPARAM)szText);
        szText[iLength]='\0';
        {
          char szClassName[128];
          int iClassLength = GetClassName(m_hWnd,szClassName,128);
          szClassName[iClassLength] = '\0';
          printf("%s  ClassName:%s\n",szText,szClassName);
        }
      } 
    }
    .............
Watch the picture,We get right edit's text when moved to login(用户名),however,We can't get nothing on passwd edit.It seems some protection after edit seting up ES_PASSWD styles.Maybe don't use WM_GETTEXT,Wathch MSDN:

Displays an asterisk (*) for each character typed into the edit control. This style is valid only for singleline edit controls.

To change the characters that is displayed, or set or clear this style, use the EM_SETPASSWORDCHAR message.

Can I get passwd if password be sent EM_SETPASSWORDCHAR first,after be sent WM_GETTEXT ? Test it,I can't get yet.

Watch other people' software,OD loaded,bp GetWindowLong.

F9 run,Drag magnifier of soft,Stop there:

00401ABC  |> \6A F0         push    -10                           ; /Index = GWL_STYLE

  00401ABE  |.  FF75 10       push    dword ptr [ebp+10]            ; |hWnd
  00401AC1  |.  FF15 0C924000 call    dword ptr [<&USER32.GetWind>  ; \GetWindowLongA
  00401AC7  |.  8BD8          mov     ebx, eax
  00401AC9  |.  8D85 D8FCFFFF lea     eax, dword ptr [ebp-328]      ;  Stack Address =0012F87C, (ASCII "EDIT")
  00401ACF  |.  68 ECB14000   push    0040B1EC                      ;  ASCII "EDIT"
  00401AD4  |.  50            push    eax                           ;  可见在GetWindowLong前面已经调用过GetClassName
  00401AD5  |.  E8 361B0000   call    00403610                      ;  test window's type of magnifier and EDIT
  00401ADA  |.  59            pop     ecx
  00401ADB  |.  85C0          test    eax, eax
  00401ADD  |.  59            pop     ecx
  00401ADE  |.  0F84 CA000000 je      00401BAE                      ;   Edit, jump keyt
  ..........

  00401BAE  |> \F6C3 20       test    bl, 20
  00401BB1  |.  74 57         je      short 00401C0A
  00401BB3  |.  833D 4CE44000>cmp     dword ptr [40E44C], 0
  00401BBA  |.^ 74 D9         je      short 00401B95
  00401BBC  |.  8D45 14       lea     eax, dword ptr [ebp+14]
  00401BBF  |.  50            push    eax
  00401BC0  |.  FF75 10       push    dword ptr [ebp+10]            ;  可以用spy查看一下,此处存放的是密码框的句柄
  00401BC3  |.  FFD7          call    edi                           ;  USER32.GetWindowThreadProcessId
  00401BC5  |.  FF75 14       push    dword ptr [ebp+14]            ; /ProcessId
  00401BC8  |.  6A 00         push    0                             ; |Inheritable = FALSE
  00401BCA  |.  68 3A040000   push    43A                           ; |Access = CREATE_THREAD|VM_OPERATION|VM_READ|VM_WRITE|QUERY_INFORMATION
  00401BCF  |.  FF15 34904000 call    dword ptr [<&KERNEL32.OpenP>  ; \OpenProcess
  00401BD5  |.  8BF0          mov     esi, eax
  00401BD7  |.  85F6          test    esi, esi
  00401BD9  |.  74 1C         je      short 00401BF7
  00401BDB  |.  8D85 D8FEFFFF lea     eax, dword ptr [ebp-128]
  00401BE1  |.  50            push    eax
  00401BE2  |.  FF75 10       push    dword ptr [ebp+10]
  00401BE5  |.  56            push    esi
  00401BE6  |.  E8 01F6FFFF   call    004011EC                       ;  keyt
  00401BEB  |.  83C4 0C       add     esp, 0C
  00401BEE  |.  56            push    esi                            ; /hObject
  00401BEF  |.  FF15 38914000 call    dword ptr [<&KERNEL32.Close>   ; \CloseHandle
  00401BF5  |.  EB 13         jmp     short 00401C0A
  00401BF7  |>  8D85 D8FEFFFF lea     eax, dword ptr [ebp-128]
  00401BFD  |.  68 50E44000   push    0040E450
  00401C02  |.  50            push    eax
  00401C03  |.  E8 98130000   call    00402FA0
  00401C08  |.  59            pop     ecx
  00401C09  |.  59            pop     ecx
  00401C0A  |>  8D85 D8FEFFFF lea     eax, dword ptr [ebp-128]
  00401C10  |.  50            push    eax                            ; /Text
  00401C11  |.  68 EC030000   push    3EC                            ; |/ControlID = 3EC (1004.)
  00401C16  |.  FF75 08       push    dword ptr [ebp+8]              ; ||hWnd
  00401C19  |.  FF15 94914000 call    dword ptr [<&USER32.GetDlgI>   ; |\GetDlgItem
  00401C1F  |.  50            push    eax                            ; |hWnd
  00401C20  |.  FF15 10924000 call    dword ptr [<&USER32.SetWind>   ; \SetWindowTextA 

  run in call    004011EC

  004011EC  /$  6A 00         push    0
  004011EE  |.  FF7424 10     push    dword ptr [esp+10]
  004011F2  |.  FF7424 10     push    dword ptr [esp+10]           ;  Edit 的句柄, 就叫它 m_EditHwnd 吧
  004011F6  |.  FF7424 10     push    dword ptr [esp+10]           ;  调用OpenProcess后返回的进程句柄 ,先叫它 m_ThreadHandle
  004011FA  |.  E8 01FEFFFF   call    00401000                     ;  某个函数,形如:Function(var1,var2,var3,var4)
  004011FF  |.  83C4 10       add     esp, 10
  00401202  \.  C3            retn[/code] 
 再跟进call    00401000    
  00401000  /$  55            push    ebp
  00401001  |.  8BEC          mov     ebp, esp
  00401003  |.  6A FF         push    -1
  00401005  |.  68 38924000   push    00409238
  0040100A  |.  68 B0314000   push    004031B0                            ;  SE 处理程序安装
  0040100F  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
  00401015  |.  50            push    eax
  00401016  |.  64:8925 00000>mov     dword ptr fs:[0], esp
  0040101D  |.  81EC 30010000 sub     esp, 130
  00401023  |.  53            push    ebx
  00401024  |.  56            push    esi
  00401025  |.  57            push    edi
  00401026  |.  33F6          xor     esi, esi
  00401028  |.  8975 E4       mov     dword ptr [ebp-1C], esi
  0040102B  |.  8975 DC       mov     dword ptr [ebp-24], esi
  0040102E  |.  8975 D0       mov     dword ptr [ebp-30], esi
  00401031  |.  8975 E0       mov     dword ptr [ebp-20], esi
  00401034  |.  8975 FC       mov     dword ptr [ebp-4], esi
  00401037  |.  68 60B04000   push    0040B060                            ; /pModule = "user32"
  0040103C  |.  FF15 6C904000 call    dword ptr [<&KERNEL32.GetModuleHa>  ; \GetModuleHandleA
  00401042  |.  8945 CC       mov     dword ptr [ebp-34], eax
  00401045  |.  3BC6          cmp     eax, esi
  00401047  |.  0F84 17010000 je      00401164
  0040104D  |.  8B45 0C       mov     eax, dword ptr [ebp+C]
  00401050  |.  8985 C4FEFFFF mov     dword ptr [ebp-13C], eax
  00401056  |.  807D 14 00    cmp     byte ptr [ebp+14], 0
  0040105A  |.  B8 50B04000   mov     eax, 0040B050                       ;  ASCII "SendMessageW"
  0040105F  |.  75 05         jnz     short 00401066
  00401061  |.  B8 40B04000   mov     eax, 0040B040                       ;  ASCII "SendMessageA"
  00401066  |>  50            push    eax                                 ; /ProcNameOrOrdinal
  00401067  |.  FF75 CC       push    dword ptr [ebp-34]                  ; |hModule
  0040106A  |.  FF15 D8904000 call    dword ptr [<&KERNEL32.GetProcAddr>  ; \GetProcAddress
  00401070  |.  8985 C8FEFFFF mov     dword ptr [ebp-138], eax            ;  获取了SendMessage 函数的地址,保存好,一会要用到
  00401076  |.  6A 40         push    40
  00401078  |.  59            pop     ecx
  00401079  |.  33C0          xor     eax, eax
  0040107B  |.  8DBD CCFEFFFF lea     edi, dword ptr [ebp-134]
  00401081  |.  F3:AB         rep     stos dword ptr es:[edi]
  00401083  |.  39B5 C8FEFFFF cmp     dword ptr [ebp-138], esi
  00401089  |.  0F84 D5000000 je      00401164
  0040108F  |.  6A 04         push    4                                   ; /flProtect = 4
  00401091  |.  68 00100000   push    1000                                ; |flAllocationType = 1000 (4096.)
  00401096  |.  BF 08010000   mov     edi, 108                            ; |
  0040109B  |.  57            push    edi                                 ; |dwSize => 108 (264.)
  0040109C  |.  56            push    esi                                 ; |lpAddress
  0040109D  |.  FF75 08       push    dword ptr [ebp+8]                   ; |hProcess
  004010A0  |.  FF15 DC904000 call    dword ptr [<&KERNEL32.VirtualAllo>  ; \VirtualAllocEx
  004010A6  |.  8945 D8       mov     dword ptr [ebp-28], eax             ;

 在 m_ThreadHandle 的虚地址空间里分配一块空间 VirMem1, 108h字节

  004010A9  |.  3BC6          cmp     eax, esi
  004010AB  |.  0F84 B3000000 je      00401164
  004010B1  |.  8D4D E0       lea     ecx, dword ptr [ebp-20]
  004010B4  |.  51            push    ecx                                 ; /pBytesWritten
  004010B5  |.  57            push    edi                                 ; |BytesToWrite => 108 (264.)
  004010B6  |.  8D8D C4FEFFFF lea     ecx, dword ptr [ebp-13C]            ; |
  004010BC  |.  51            push    ecx                                 ; |Buffer = 0012F60C
  004010BD  |.  50            push    eax                                 ; |Address = D60000
  004010BE  |.  FF75 08       push    dword ptr [ebp+8]                   ; |hProcess = 00000088 (window)
  004010C1  |.  8B1D E0904000 mov     ebx, dword ptr [<&KERNEL32.WriteP>  ; |kernel32.WriteProcessMemory
  004010C7  |.  FFD3          call    ebx                                 ; \WriteProcessMemory

Start from buffer = 0012F60C,VirMem1 is be write something,follow buffer to point address on data window,We can find that 0008093E is handle of Edit and 772DF3B7 is SendMessage address.
Then look down:

  004010C9  |.  BE EB114000   mov     esi, 004011EB
  004010CE  |.  81EE CB114000 sub     esi, 004011CB
  004010D4  |.  89B5 C0FEFFFF mov     dword ptr [ebp-140], esi
  004010DA  |.  6A 40         push    40                                  ; /flProtect = 40 (64.)
  004010DC  |.  68 00100000   push    1000                                ; |flAllocationType = 1000 (4096.)
  004010E1  |.  56            push    esi                                 ; |dwSize => 20 (32.)
  004010E2  |.  6A 00         push    0                                   ; |lpAddress = NULL
  004010E4  |.  FF75 08       push    dword ptr [ebp+8]                   ; |hProcess = 00000088 (window)
  004010E7  |.  FF15 DC904000 call    dword ptr [<&KERNEL32.VirtualAllo>  ; \VirtualAllocEx

VirtualAlloc VirMem2,

  004010ED  |.  8945 D4       mov     dword ptr [ebp-2C], eax               ;  分配的内存地址: D70000
  004010F0  |.  85C0          test    eax, eax
  004010F2  |.  74 6E         je      short 00401162
  004010F4  |.  8D4D E0       lea     ecx, dword ptr [ebp-20]
  004010F7  |.  51            push    ecx                                   ; /pBytesWritten
  004010F8  |.  56            push    esi                                   ; |BytesToWrite => 20 (32.)
  004010F9  |.  68 CB114000   push    004011CB                              ; |Buffer = ViewPass.004011CB
  004010FE  |.  50            push    eax                                   ; |Address = D70000
  004010FF  |.  FF75 08       push    dword ptr [ebp+8]                     ; |hProcess = 00000088 (window)
  00401102  |.  FFD3          call    ebx                                   ; \WriteProcessMemory

Buffer = ViewPass.004011CB,Right menu select "Disassembly",show it:

  004011CB   .  56                    push    esi
  004011CC   .  8B7424 08             mov     esi, dword ptr [esp+8]
  004011D0   .  8D46 08               lea     eax, dword ptr [esi+8]
  004011D3   .  50                    push    eax
  004011D4   .  68 00010000           push    100
  004011D9   .  6A 0D                 push    0D
  004011DB   .  FF36                  push    dword ptr [esi]
  004011DD   .  FF56 04               call    dword ptr [esi+4]
  004011E0   .  80A6 07010000 00      and     byte ptr [esi+107], 0
  004011E7   .  5E                    pop     esi
  004011E8   .  C2 0400               retn    4

Next watch,Later analyse what to do.

  00401104  |.  8D45 DC       lea     eax, dword ptr [ebp-24]
  00401107  |.  50            push    eax                                   ; /lpThreadId
  00401108  |.  33F6          xor     esi, esi                              ; |
  0040110A  |.  56            push    esi                                   ; |dwCreationFlags => 0
  0040110B  |.  FF75 D8       push    dword ptr [ebp-28]                    ; |lpParameter => 00D60000
  0040110E  |.  FF75 D4       push    dword ptr [ebp-2C]                    ; |lpStartAddress = 00D70000
  00401111  |.  56            push    esi                                   ; |dwStackSize => 0
  00401112  |.  56            push    esi                                   ; |lpThreadAttributes => 0
  00401113  |.  FF75 08       push    dword ptr [ebp+8]                     ; |hProcess = 00000088 (window)
  00401116  |.  FF15 E4904000 call    dword ptr [<&KERNEL32.CreateRemoteT>  ; \CreateRemoteThread   

m_ThreadHandle create a process,m_ThreadHandle through OpenProcess to get when create password be create.lpStartAddress = 00D70000 The thread create to finished.Software will execute from here on.  lpParameter => 00D60000,That is transmitt parameter for the thread.

Analyse VirMem2 to write code.
  004011CB   .  56            push    esi           
  004011CC   .  8B7424 08     mov     esi, dword ptr [esp+8]       ;参数 00D60000   
  004011D0   .  8D46 08       lea     eax, dword ptr [esi+8]       ;00D60008,save passwd  
  004011D3   .  50            push    eax                          ;WM_GETTEXT get string address     
  004011D4   .  68 00010000   push    100                          ;最多返回100h个字符   
  004011D9   .  6A 0D         push    0D                           ;WM_GETTEXT   
  004011DB   .  FF36          push    dword ptr [esi]              ;Password's handle
  004011DD   .  FF56 04       call    dword ptr [esi+4]            ;SendMessage's address
  004011E0   .  80A6 07010000>and     byte ptr [esi+107], 0        ;'\0 '
  004011E7   .  5E            pop     esi
  004011E8   .  C2 0400       retn    4

Recalled the call doing:
1. push parameter
2. push return address
3. call interrupt
4. return from interrupt


New thread take as a function,Assume esp to point 00000018,Get the model.

    Stack         Content
    000010      push esi
    000014      return address
    000018      for thread transmit parameter 00D60000
    00001C 
    000020
    000024

Main analyse finished,Watch next:

  0040111C  |.  8945 E4       mov     dword ptr [ebp-1C], eax
  0040111F  |.  3BC6          cmp     eax, esi
  00401121  |.  74 3F         je      short 00401162
  00401123  |.  6A FF         push    -1                                    ; /Timeout = INFINITE
  00401125  |.  50            push    eax                                   ; |hObject = 00000098 (window)
  00401126  |.  FF15 EC904000 call    dword ptr [<&KERNEL32.WaitForSingle>  ; \WaitForSingleObject
 
  0040112C  |.  8D45 E0       lea     eax, dword ptr [ebp-20]
  0040112F  |.  50            push    eax                                   ; /pBytesRead
  00401130  |.  57            push    edi                                   ; |BytesToRead => 108 (264.)
  00401131  |.  8D85 C4FEFFFF lea     eax, dword ptr [ebp-13C]              ; |
  00401137  |.  50            push    eax                                   ; |Buffer = 0012F60C
  00401138  |.  FF75 D8       push    dword ptr [ebp-28]                    ; |pBaseAddress = D60000
  0040113B  |.  FF75 08       push    dword ptr [ebp+8]                     ; |hProcess = 00000088 (window)
  0040113E  |.  FF15 90904000 call    dword ptr [<&KERNEL32.ReadProcessMe>  ; \ReadProcessMemory

Get passwd finished.

Flow:
1.Get edit's handle.
2.GetWindowThreadProcessId() get to create edit's id.
3.OpenProcess(); Open the thread's object,Get the object's HANDLE;
4.Virtual memory at remote thread,write my code.
5.Create remote thread to create my code.
6.Return result.
7.Free momery.

Attach code:

code:
 //定义全局变量
  static BYTE RemoteCode[]=
  {
    "\x56\x8B\x74\x24\x08\x8D\x46\x08"

    "\x50\x68\x00\x01\x00\x00\x6A\x0D"

    "\xFF\x36\xFF\x56\x04\x80\xA6\x07"

    "\x01\x00\x00\x00\x5E\xC2\x04\x00"

  };

  struct Parameter{

    HWND    hWnd;

    FARPROC    pProc;

    DWORD    dwBuffer[128];

    Parameter()
    {

      hWnd  =0;

      pProc =0;

      memset(dwBuffer,0,sizeof(dwBuffer));

    }

  }; 

  Parameter RemoteParmeter;

code:
void CPWDLookDlg::GetPassWord(HWND hWnd)
{

    try{

      RemoteParmeter.hWnd = hWnd;

      DWORD  m_ThreadID = 0;

      GetWindowThreadProcessId(hWnd,&m_ThreadID);

      HANDLE  m_ThreadHandle = ::OpenProcess(0x43A,FALSE,m_ThreadID);

      if(!m_ThreadHandle)  { return; }

      HMODULE m_Usr32Mod = GetModuleHandle("user32");

      FARPROC m_SendMessageFun = GetProcAddress(m_Usr32Mod,"SendMessageA");

      RemoteParmeter.pProc = m_SendMessageFun;

      LPVOID  m_VirMem1 = VirtualAllocEx(m_ThreadHandle,NULL,sizeof(RemoteParmeter),MEM_COMMIT,PAGE_READWRITE);

      if(!m_VirMem1) { return; }

      if(!WriteProcessMemory(m_ThreadHandle,m_VirMem1, &RemoteParmeter,sizeof(RemoteParmeter),NULL)) {return;}

      LPVOID  m_VirMem2 = VirtualAllocEx(m_ThreadHandle,NULL,sizeof(RemoteCode),MEM_COMMIT,PAGE_EXECUTE_READWRITE);

      if(!m_VirMem2) { return; }

      if(!WriteProcessMemory(m_ThreadHandle,m_VirMem2, RemoteCode,sizeof(RemoteCode),NULL)){return;}

      HANDLE m_RemoteThreadHandle =
        CreateRemoteThread(m_ThreadHandle,NULL,NULL,(LPTHREAD_START_ROUTINE)m_VirMem2,m_VirMem1,NULL,NULL);

      if(!m_RemoteThreadHandle) { return; }

      WaitForSingleObject(m_RemoteThreadHandle,INFINITE);

      if(!ReadProcessMemory(m_ThreadHandle,m_VirMem1 ,&RemoteParmeter,sizeof(RemoteParmeter),NULL)) {return;}

      CString m_strPwd;

      m_strPwd.Format("%s",RemoteParmeter.dwBuffer);

      m_ediPWord.SetWindowText(m_strPwd);

      VirtualFreeEx(m_ThreadHandle,m_VirMem1,0,MEM_RELEASE);

      VirtualFreeEx(m_ThreadHandle,m_VirMem2,0,MEM_RELEASE);

      DWORD lpExitCode;

      GetExitCodeThread(m_RemoteThreadHandle ,&lpExitCode);

      CloseHandle(m_RemoteThreadHandle);

      CloseHandle(m_ThreadHandle);

    }catch(...)

    {
      AfxMessageBox("Error!");
    }

}

No comments:

Post a Comment