SDK程序员经常写出的一段低效率代码[代码优化][原] 由于新版本的 MafaLSHelper v1.0 Standard 在编写当中需要涉及到一些更加复杂的操作,将导致以前用MASM32所编写的Utils.dll函数库供不应求,所以目前需要新增一批函数!如下列表:
------------------------------------------------------------------------------------------------------ 1) MStrFindA(ANSI)、MStrFindW(UNICODE);攻能:查找字符串,并返回结果串,失败为0。 2) MStrCmpA(ANSI)、MStrCmpW(UNICODE);攻能:比较字符串,和strcmp一样。 3) MStrCmpiA(ANSI)、MStrCmpiW(UNICODE);攻能:比较字符串,和strcmpi一样。 4) MStrNCmpA(ANSI)、MStrNCmpW(UNICODE);攻能:比较指定的N个字符串,和strcmpN一样。 5) MGetAbsolutePathA(ANSI)、MGetAbsolutePathW(UNICODE);攻能:从相对路径中获取绝对路径。 6) MGetRelativePathA(ANSI)、MGetRelativePathW(UNICODE);攻能:从绝对路径获取相对路径。 ------------------------------------------------------------------------------------------------------
第一个函数即刻可从MStrRepA/W简化过来的。但是,众所周知社会在发展,人也一样,所以编程思想也在不断地进步,显然,代码质量也就相应的有所提高了…… 所以不是再那么简单地从MStrRepA/W简化过来了,事情变的更加地复杂,我不得不重新大规模地修改至少80%处左右的代码…… 因此,为了能在编写的过程中可以更加快速的查看寄存器的变化,于是我在DLL内新增加了一个能显示当前寄存器的MessageBox。该函数前提地需要不能影响当前的所有寄存器及标志寄存器内的值。代码如下: ----------------------------------------------------------------------------- MASM32 code: MsgInfo PROC C pszFormat:DWORD, args:VARARG LOCAL szBuffer[6400]:BYTE PUSHAD
为了更大程度的优化代码,于是,我便用OllyDbg进行了如下反汇编DLL,结果MsgInfo函数出来的代码如下:
OllyDbg Code: 10001000 55 push ebp
大家可以看出,MASM32写的代码,几乎和反汇编出来的结果一样!很惊奇吧?J -----------------------------------------------------------------------------
说了那么多的废话,几乎都完全脱离主题了……汗一个先,不过总得让大家知道,我是因为什么才会拿出牛刀OllyDbg来调试我的C程序的……
现在我们来看一段SDK的代码:
///
//; MStrFindA MASM32 原型 //MStrFindA proto pszExpression:DWORD, pszFind:DWORD, nStart:DWORD, nCount:DWORD
// C声明原型 EXPORT LPSTR MStrFindA( LPSTR pszExpression, LPCSTR pszFind, int nStart, int nCount );
#ifndef _UNICODE #define MStrFindEx MStrFindA #else #define MStrFindEx MStrFindW #endif
#define MStrFind(pszExpression,pszFind) / MStrFindEx(pszExpression,pszFind,-1,-1);
///
int main(int argc, char** argv) { TCHAR szDst[260] = TEXT("abcdef"); TCHAR szFind[260] = TEXT("f"); PTSTR pFound = NULL;
pFound = MStrFind( szDst, szFind );
_tprintf( TEXT("result of found:[%s]/n"), pFound );
return 0; }
现在再来看看main函数的反汇编结果:
; 当前进程栈向下伸长208H个字节:260D + 260D = 520D 00401000 /$ >sub esp, 208
; 获取堆中的常量串: TEXT("abcdef")
;备份edi
; 完成 TCHAR szDst[260] = TEXT("abcdef"); 的赋值...
; 获取堆中的常量串:TEXT("f")
; 1、完成 TCHAR szFind[260] = TEXT("f"); 的赋值;2、完成MStrFindA函数的参数压栈。
; 调用_tprintf显示结果 ; 确定return 0的0值 00401078 |. >xor eax, eax ; return 0;
; 恢复 edi ; 恢复局部变量占用栈 0040107B |. >add esp, 208
///
经过上面的反汇编结果,我想SDK程序员应该都非常地清楚的在定义一个序列串时,如果初始化一个值给它,会有怎么样的结果! 汗不汗你?应该是满头了吧?这样还好点,最恐怖的就是出现如下面这样的代码:
TCHAR szFind[260] = TEXT("/0");
strcpy( szFind, TEXT("abc") );
我可以很直接地告诉你,第一条声明和赋值语句,会和上面反汇编的代码一样地处理(虽然它仅仅就是一个NULL),然后再进行CALL strcpy进行拷贝abc/0,怎么样?冒冷汗了吧你?所以大家以后写代码千万要小心了!在定义一个局部串时,如果真想要给他一个NULL,可以这样用:
TCHAR szFind[260]; *szFind = TEXT('/0');
你应该也猜到了吧,这行代码将转换成如下形式: mov byte ptr ss:[esp+N个偏移], 0
嘿嘿!不会再那么傻呼呼地原原版版地进行260个字节逐个进行一一地串门了吧。
By dreamerate at home written in 2007-6-7 01:13 dreamerate@gmail.com |