能力值:
( LV2,RANK:10 )
3 楼
暂停在ntdll 里面的
7C93B1FA上,下步不知道怎么操作了,多谢指教,下面是抓的暂停函数反汇编代码
7C93B19F > 8BFF mov edi, edi
7C93B1A1 55 push ebp
7C93B1A2 8BEC mov ebp, esp
7C93B1A4 83EC 68 sub esp, 68
7C93B1A7 53 push ebx
7C93B1A8 56 push esi
7C93B1A9 8B75 08 mov esi, dword ptr [ebp+8]
7C93B1AC 33DB xor ebx, ebx
7C93B1AE 81FE 78B1997C cmp esi, 7C99B178
7C93B1B4 895D F8 mov dword ptr [ebp-8], ebx
7C93B1B7 0F9445 0B sete byte ptr [ebp+B]
7C93B1BB 64:A1 18000000 mov eax, dword ptr fs:[18]
7C93B1C1 0FB64D 0B movzx ecx, byte ptr [ebp+B]
7C93B1C5 8988 840F0000 mov dword ptr [eax+F84], ecx
7C93B1CB 381D C4B0997C cmp byte ptr [7C99B0C4], bl
7C93B1D1 ^ 0F85 0C89FFFF jnz 7C933AE3
7C93B1D7 A0 E8B1997C mov al, byte ptr [7C99B1E8]
7C93B1DC F6D8 neg al
7C93B1DE 57 push edi
7C93B1DF 1BC0 sbb eax, eax
7C93B1E1 F7D0 not eax
7C93B1E3 25 E0B1997C and eax, 7C99B1E0
7C93B1E8 8BF8 mov edi, eax
7C93B1EA 8B46 10 mov eax, dword ptr [esi+10]
7C93B1ED 3BC3 cmp eax, ebx
7C93B1EF 8945 FC mov dword ptr [ebp-4], eax
7C93B1F2 0F84 9E000000 je 7C93B296
7C93B1F8 8B06 mov eax, dword ptr [esi]
7C93B1FA FF40 10 inc dword ptr [eax+10]
7C93B1FD 8B45 FC mov eax, dword ptr [ebp-4]
7C93B200 83E0 01 and eax, 1
7C93B203 8945 E8 mov dword ptr [ebp-18], eax
7C93B206 8B06 mov eax, dword ptr [esi]
7C93B208 FF40 14 inc dword ptr [eax+14]
7C93B20B F605 F002FE7F 0>test byte ptr [7FFE02F0], 1
7C93B212 0F85 2E690200 jnz 7C961B46
7C93B218 395D E8 cmp dword ptr [ebp-18], ebx
7C93B21B 57 push edi
7C93B21C 53 push ebx
7C93B21D 0F85 E8840100 jnz 7C95370B
7C93B223 FF75 FC push dword ptr [ebp-4]
7C93B226 E8 052DFFFF call ZwWaitForSingleObject
7C93B22B 3D 02010000 cmp eax, 102
7C93B230 0F84 9B690200 je 7C961BD1
7C93B236 3BC3 cmp eax, ebx
7C93B238 0F8C 506A0200 jl 7C961C8E
7C93B23E 385D 0B cmp byte ptr [ebp+B], bl
7C93B241 5F pop edi
7C93B242 74 18 je short 7C93B25C
7C93B244 64:A1 18000000 mov eax, dword ptr fs:[18]
7C93B24A 8B40 24 mov eax, dword ptr [eax+24]
7C93B24D 8946 0C mov dword ptr [esi+C], eax
7C93B250 64:A1 18000000 mov eax, dword ptr fs:[18]
7C93B256 8998 840F0000 mov dword ptr [eax+F84], ebx
7C93B25C 5E pop esi
7C93B25D 5B pop ebx
7C93B25E C9 leave
7C93B25F C2 0400 retn 4
能力值:
( LV2,RANK:10 )
8 楼
olldbg跟踪,停在系统代码GDI32里,报"0x77efaaa6" 指令引用的"0x00000044"内存.该内存不能为"written"不知怎么调试了
但是注释掉
_Strrchr proc uses edi ecx ebx
; jmp @f
invoke lstrlen,offset szPath
lea ebx,offset szPath
add ebx,eax
std
mov edi, ebx
mov ecx,eax
mov al,5ch
repne scasb
inc edi
xor eax,eax
mov [edi], al
;@@:
; invoke MessageBox,NULL,offset szPath,offset szCaptionMain,MB_OK
ret
_Strrchr endp
这段代码就正常,其实这段代码就 lstrlen 我用了系统的!
能力值:
( LV2,RANK:10 )
9 楼
完整程序是这样的,用ollydbg调试忽略内存异常发现一个奇怪的现象!
.586
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include shlwapi.inc
includelib shlwapi.lib
ID_TIMER equ 1
IDI_GUARDIAN equ 1
.data?
hInstance dd ?
hWndMain dd ?
szPath db [MAX_PATH] dup (?)
szTmp db [MAX_PATH] dup(?)
.const
szClassName db 'Guardian',0
szCaptionMain db 'GuardianServerMate',0
szText db '守护程序!',0
szMutexText db 'ServerMate',0
szExecuteName db 'ServerMate.exe',0
szAddText db '\ServerMate.exe',0
szInfoText db '程序不完整,要启动吗?',0
.code
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
local @hDc
local @hMutex:HANDLE
local @stInfo
local @pInfo:PROCESS_INFORMATION
mov eax,uMsg
.if eax == WM_TIMER
invoke CreateMutex,NULL,FALSE,offset szMutexText
mov ebx,eax
invoke GetLastError
.if eax == ERROR_ALREADY_EXISTS
invoke CloseHandle,ebx
invoke GetStartupInfo,addr @stInfo
invoke CreateProcess,offset szExecuteName,NULL,NULL,NULL,NULL,\
NORMAL_PRIORITY_CLASS,NULL,NULL,addr @stInfo,addr @pInfo
.endif
.elseif eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax
invoke GetClientRect,hWnd,addr @stRect
invoke DrawText,@hDc,offset szText,-1,addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint,hWnd,addr @stPs
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWnd
invoke KillTimer,hWnd,ID_TIMER
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
; ---------------------------------------------
; 注册窗口
; ---------------------------------------------
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke LoadIcon,hInstance,IDI_GUARDIAN
mov @stWndClass.hIcon,eax
mov @stWndClass.hIconSm,eax
invoke RegisterClassEx,addr @stWndClass
; ---------------------------------------------
; 创建窗口
; ---------------------------------------------
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL
mov hWndMain,eax
invoke SetTimer,hWndMain,ID_TIMER,1000,NULL
invoke ShowWindow,hWndMain,SW_SHOWNORMAL
invoke UpdateWindow,hWndMain
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
_Strrchr proc uses edi ecx ebx
; jmp @f
invoke lstrlen,offset szPath
lea ebx,offset szPath
add ebx,eax
std
mov edi, ebx
mov ecx,eax
mov al,5ch
repne scasb
inc edi
xor eax,eax
mov [edi], al
;@@:
; invoke MessageBox,NULL,offset szPath,offset szCaptionMain,MB_OK
ret
_Strrchr endp
_PreProc proc
invoke GetModuleFileName,NULL,offset szPath,MAX_PATH
call _Strrchr
;前面执行正常截断字符串,但是下面API调用过后,字符串却是一个莫名其妙的值...!
invoke lstrcat,offset szPath,offset szAddText
; invoke MessageBox,NULL,offset szPath,offset szCaptionMain,MB_OK
invoke PathFileExists,offset szPath
.if !eax
invoke MessageBox,NULL,offset szInfoText,offset szCaptionMain,MB_OKCANCEL
.if eax != 1
invoke ExitProcess,NULL
.endif
.endif
ret
_PreProc endp
start:
call _PreProc
call _WinMain
invoke ExitProcess,NULL
end start
能力值:
( LV2,RANK:10 )
15 楼
// Guardian.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include "shlwapi.h"
#pragma comment(lib,"Shlwapi.lib")
#define ID_TIMER 1
// Global Variables:
HINSTANCE hInst;
HWND hWnd;
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
TCHAR szPath[MAX_PATH];
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
GetModuleFileName( NULL , szPath , MAX_PATH );
*strrchr( szPath,'\\') = NULL;
strcat( szPath, "\\ServerMate.exe");
if(!PathFileExists(szPath))
if(1 != MessageBox(hWnd,"程序不完整,要启动吗?","提示",MB_OKCANCEL))
{
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_GUARDIAN);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "GUARDIAN";
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_GUARDIAN);
return RegisterClassEx(&wcex);
} BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow("GUARDIAN","ServerMateGuardian", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
SetTimer(hWnd,ID_TIMER,1000,NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
} LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HANDLE hMutex;
STARTUPINFO stinfo;
PROCESS_INFORMATION pinfo;
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_TIMER:
hMutex = CreateMutex(NULL, FALSE, "ServerMate");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
CloseHandle(hMutex);
GetStartupInfo(&stinfo);
CreateProcess("ServerMate.exe",NULL,NULL,NULL,NULL,
NORMAL_PRIORITY_CLASS,NULL,NULL,&stinfo,&pinfo);
hMutex = NULL;
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, "szHello", strlen("szHello"), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
KillTimer (hWnd,ID_TIMER);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
这是C版本的
能力值:
( LV9,RANK:170 )
19 楼
char * strrchr(const char *s, char c)
--------------------------------------------------
比较正统的汇编版:
__strrchr:
push ebp
mov ebp, esp
mov edi, [ebp+8] ; char *s
movzx ebx, byte ptr [ebp+0x0c] ; char c
xor eax, eax
ll:
movzx edx, byte ptr [edi]
test edx, edx
jz done
cmp edx, ebx
jnz lll
mov eax, edi
lll:
inc edi
jmp ll
done:
mov esp, ebp
pop ebp
ret
能力值:
( LV2,RANK:10 )
21 楼
谢谢mik,我加进去测试一下
其实我偷了个懒直接用下面代码,来实现截断字符串的功能!
_Strrchr proc uses edi ecx ebx
invoke lstrlen,offset szPath
lea ebx,offset szPath
add ebx,eax
std
mov edi, ebx
mov ecx,eax
mov al,5ch
repne scasb
inc edi
xor eax,eax
mov [edi], al
ret
_Strrchr endp
能力值:
( LV9,RANK:170 )
23 楼
char *my_strrchr(const char *s, char c) { __asm { mov edi, [ebp+8] ; char *s movzx ebx, byte ptr [ebp+0xc] ; char c xor eax, eax ll: movzx edx, byte ptr [edi] test edx, edx jz done cmp edx, ebx jnz lll mov eax, edi lll: inc edi jmp ll done: } } void test() { LARGE_INTEGER l,start,end; double interval; double freq; QueryPerformanceFrequency(&l); freq = (double)l.QuadPart; int i = 0; char *p = 0; char *s = "mikik"; QueryPerformanceCounter(&start); for (i = 0; i < 10000000u; i++) p = strrchr(s, 'i'); QueryPerformanceCounter(&end); printf("%c at %x\n",'i',p); interval = (double)(end.QuadPart - start.QuadPart); printf("strrchr(): time is: %g ms\n", interval*1000/freq); /////////////////////////////////////////////////////////////////////////////////// QueryPerformanceCounter(&start); for (i = 0; i < 10000000u; i++) p = my_strrchr(s, 'i'); QueryPerformanceCounter(&end); printf("%c at %x\n",'i',p); interval = (double)(end.QuadPart - start.QuadPart); printf("my_strrchr(): time is: %g ms\n", interval*1000/freq); } 贴出我的测试结果:
i at f3574f
strrchr(): time is: 672.535 ms
i at f3574f
my_strrchr(): time is: 432.899 ms 我上面写的 my_strrchr() 比系统的 strrchr() 快多了。 哈哈哈