标签:
Windows XP 系统自带扑克牌资源动态链接库cards.dll逆向分析笔记WEP cdtAnimate cdtDraw cdtDrawExt cdtInit cdtTerm DllEntryPoint
代码: HINSTANCE hDllModule; //全局变量 BOOL DllMain (HINSTANCE hInstDll, DWORD dwReason, LPVOID lpReserved) { hDllModule = hInstDll; return TRUE; }
代码: BOOL __stdcall WEP (int Arg1) { return TRUE; } BOOL __stdcall cdtAnimate (int Arg1, int Arg2, int Arg3, int Arg4, int Arg5) { return TRUE; }
代码: //全局变量 int nNormalWidth; //正常大小下卡片的宽 int nNormalHeight; //正常大小下卡片的长 int nInitCount = 0; //“初始化计数”,每调用cdtInit一次增加1, //每调用cdtTerm一次减少1 HBITMAP hPlainBack = NULL; //平实型背面的位图句柄 HBITMAP hCrossBack = NULL; //斜十字图案型背面的位图句柄 HBITMAP hCircleBack = NULL; //圆圈图案型背面的位图句柄 //函数定义体 BOOL __stdcall cdtInit (LPINT lpNormalWidth, LPINT lpNormalHeight) { BITMAP loc_stBM; if (nInitCount++ == 0) { hPlainBack = LoadBitmap (hDllModule, 53); hCrossBack = LoadBitmap (hDllModule, 67); hCircleBack = LoadBitmap (hDllModule, 68); if (hPlainBack == NULL || hCrossBack == NULL || hCircleBack == NULL) { MyDeleteHbm (hPlainBack); MyDeleteHbm (hCrossBack); MyDeleteHbm (hCircleBack); return FALSE; } GetObject (hPlainBack, sizeof(BITMAP), &loc_stBM); nNormalWidth = *lpNormalWidth = loc_stBM.bmWidth; nNormalHeight = *lpNormalHeight = loc_stBM.bmHeight; }else{ *lpNormalWidth = nNormalWidth; *lpNormalHeight = nNormalHeight; } return TRUE; }
代码: void __stdcall MyDeleteHbm (HBITMAP hBM) { if (hBM) DeleteObject (hBM); return; }
代码: //全局变量 HBITMAP hCards[52]; //一副扑克牌的位图句柄 HBITMAP hCustomBack; //自选的卡片背面的位图句柄 //函数定义体 void cdtTerm (void) { int loc_i; if (--nInitCount <= 0) { for (loc_i = 0; loc_i < 52; loc_i++) MyDeleteHbm (hCards[loc_i]); MyDeleteHbm (hPlainBack); MyDeleteHbm (hCustomBack); MyDeleteHbm (hCrossBack); MyDeleteHbm (hCircleBack); } return; }
代码: BOOL __stdcall cdtDrawExt (HDC hDC, //将要绘画的目标设备环境句柄 int nXDest, //nXDest和nYDest两个参数表示一个点的x和y坐标 int nYDest, //以该点为左上角绘画卡片 int nActualWidth, int nActualHeight, //以上两个参数表示所绘卡片的实际宽和长 int nIndexOfCard, //指定所绘卡片的序号 DWORD dwDrawingOption, //绘画方式选项 COLORREF crBackColor //背景色 ) { COLORREF loc_crCornerData[12]; //卡片四个角的颜色数据。用于圆角方式绘画卡片 COLORREF loc_crBkColor = crBackColor; //拷贝一份crBackColor的值 static HGDIOBJ hObjectToDraw; POINT loc_stP1; int loc_dwA; //代表寄存器eax DWORD loc_dwROP = 0; //ROP码 DWORD loc_dwDO = dwDrawingOption; //拷贝一份dwDrawingOption的值 BOOL loc_bSharpCorner = FALSE; //绘画卡片时选择圆角或尖角 HGDIOBJ loc_hObj1; HDC loc_hCompDC; //这两个变量都代表反汇编文本中的arg_8(Arg3) if (loc_dwDO & 0x80000000) { loc_dwDO -= 0x80000000; loc_bSharpCorner = TRUE; } if (loc_dwDO <= 7) { switch (loc_dwDO) { case 0: hObjectToDraw = _LoadCard (nIndexOfCard); loc_dwROP = SRCCOPY; loc_crBkColor = 0xFFFFFF; //白色背景 break; case 1: if (FLoadBack (nIndexOfCard) == FALSE) return FALSE; hObjectToDraw = hCustomBack; loc_dwROP = SRCCOPY; break; case 2: hObjectToDraw = _LoadCard (nIndexOfCard); loc_dwROP = NOTSRCCOPY; //反色绘制卡片 break; case 3: case 4: if ((loc_hObj1 = CreateSolidBrush (loc_crBkColor)) == NULL) return FALSE; GetDCOrgEx (hDC, &loc_stP1); SetBrushOrgEx (hDC, loc_stP1.x, loc_stP1.y, NULL); if ((loc_hObj1 = SelectObject (hDC, loc_hObj1)) != NULL) { PatBlt (hDC, nXDest, nYDest, nActualWidth, nActualHeight, PATCOPY); //在卡片区域涂上crBackColor指定的颜色 if ((loc_dwA = (int)SelectObject (hDC, loc_hObj1)) != NULL) DeleteObject ((HGDIOBJ)loc_dwA); //恢复DC中原来的画刷对象,并删除临时对象 } if (loc_dwDO == 4) return TRUE; //如果dwDrawingOption等于4,则只着色,不进一步绘画背面 //掉入下一分支,继续 case 5: hObjectToDraw = hPlainBack; loc_dwROP = SRCAND; break; case 6: hObjectToDraw = hCrossBack; loc_dwROP = SRCCOPY; break; case 7: hObjectToDraw = hCircleBack; loc_dwROP = SRCCOPY; } } if (hObjectToDraw == NULL || (loc_hCompDC = CreateCompatibleDC (hDC)) == NULL) return FALSE; if ((hObjectToDraw = SelectObject (loc_hCompDC, hObjectToDraw)) == NULL) { DeleteDC (loc_hCompDC); return TRUE; //这里明显意味着绘画失败,为什么会返回TRUE呢? } loc_crBkColor = SetBkColor (hDC, loc_crBkColor); //设置hDC背景色 if (loc_bSharpCorner == FALSE) SaveCorners (hDC, loc_crCornerData, nXDest, nYDest, nActualWidth, nActualHeight); //画卡片 if (nActualWidth == nNormalWidth && nActualHeight == nNormalHeight) { BitBlt (hDC, nXDest, nYDest, nNormalWidth, nNormalHeight, loc_hCompDC, 0, 0, loc_dwROP); }else{ StretchBlt (hDC, nXDest, nYDest, nActualWidth, nActualHeight, loc_hCompDC, 0, 0, nNormalWidth, nNormalHeight, loc_dwROP); } SelectObject (loc_hCompDC, hObjectToDraw); //恢复loc_hCompDC中原对象 if (loc_dwDO == 0) { loc_dwA = (nIndexOfCard / 4) % 13 + (nIndexOfCard % 4) * 13 + 1; if (loc_dwA >= 14 && loc_dwA <= 23 || loc_dwA >= 27 && loc_dwA <= 36) { //如果要绘画的卡片是红心A至10或方块A至10,则给它们画上黑色边框。 //注意在资源中看到的这几张牌原本是带红色边框的 PatBlt (hDC, nXDest + 2, nYDest, nActualWidth - 4, 1, BLACKNESS); PatBlt (hDC, nXDest + nActualWidth - 1, nYDest + 2, 1, nActualHeight - 4, BLACKNESS); PatBlt (hDC, nXDest + 2, nYDest + nActualHeight - 1, nActualWidth - 4, 1, BLACKNESS); PatBlt (hDC, nXDest, nYDest + 2, 1, nActualHeight - 4, BLACKNESS); SetPixel (hDC, nXDest + 1, nYDest + 1, 0x0); SetPixel (hDC, nXDest + nActualWidth - 2, nYDest + 1, 0x0); SetPixel (hDC, nXDest + nActualWidth - 2, nYDest + nActualHeight - 2, 0x0); SetPixel (hDC, nXDest + 1, nYDest + nActualHeight - 2, 0x0); } } if (loc_bSharpCorner == FALSE) RestoreCorners (hDC, loc_crCornerData, nXDest, nYDest, nActualWidth, nActualHeight); SetBkColor (hDC, loc_crBkColor); //恢复hDC原来的背景色 DeleteDC (loc_hCompDC); return TRUE; }
代码: void __stdcall SaveCorners (HDC hDC, LPCOLORREF lpcrCornerData, int nXLeft, int nYLeft, int nWidth, int nHeight) { if (nWidth == nNormalWidth && nHeight == nNormalHeight) //对于正常尺寸的卡片,存储其四个角的颜色数据 { lpcrCornerData[0] = GetPixel (hDC, nXLeft, nYLeft); lpcrCornerData[1] = GetPixel (hDC, nXLeft + 1, nYLeft); lpcrCornerData[2] = GetPixel (hDC, nXLeft, nYLeft + 1); //左上角 lpcrCornerData[3] = GetPixel (hDC, nXLeft + nWidth - 1, nYLeft); lpcrCornerData[4] = GetPixel (hDC, nXLeft + nWidth - 2, nYLeft); lpcrCornerData[5] = GetPixel (hDC, nXLeft + nWidth - 1, nYLeft + 1); //右上角 lpcrCornerData[6] = GetPixel (hDC, nXLeft + nWidth - 1, nYLeft + nHeight - 1); lpcrCornerData[7] = GetPixel (hDC, nXLeft + nWidth - 1, nYLeft + nHeight - 2); lpcrCornerData[8] = GetPixel (hDC, nXLeft + nWidth - 2, nYLeft + nHeight - 1); //右下角 lpcrCornerData[9] = GetPixel (hDC, nXLeft, nYLeft + nHeight - 1); lpcrCornerData[10] = GetPixel (hDC, nXLeft + 1, nYLeft + nHeight - 1); lpcrCornerData[11] = GetPixel (hDC, nXLeft, nYLeft + nHeight - 2); //左下角 } return; } void __stdcall RestoreCorners (HDC hDC, LPCOLORREF lpcrCornerData, int nXLeft, int nYLeft, int nWidth, int nHeight) { if (nWidth == nNormalWidth && nHeight == nNormalHeight) //将由SaveCorners所存储的颜色数据恢复到卡片四角 { SetPixel (hDC, nXLeft, nYLeft, lpcrCornerData[0]); SetPixel (hDC, nXLeft + 1, nYLeft, lpcrCornerData[1]); SetPixel (hDC, nXLeft, nYLeft + 1, lpcrCornerData[2]); SetPixel (hDC, nXLeft + nWidth - 1, nYLeft, lpcrCornerData[3]); SetPixel (hDC, nXLeft + nWidth - 2, nYLeft, lpcrCornerData[4]); SetPixel (hDC, nXLeft + nWidth - 1, nYLeft + 1, lpcrCornerData[5]); SetPixel (hDC, nXLeft + nWidth - 1, nYLeft + nHeight - 1, lpcrCornerData[6]); SetPixel (hDC, nXLeft + nWidth - 1, nYLeft + nHeight - 2, lpcrCornerData[7]); SetPixel (hDC, nXLeft + nWidth - 2, nYLeft + nHeight - 1, lpcrCornerData[8]); SetPixel (hDC, nXLeft, nYLeft + nHeight - 1, lpcrCornerData[9]); SetPixel (hDC, nXLeft + 1, nYLeft + nHeight - 1, lpcrCornerData[10]); SetPixel (hDC, nXLeft, nYLeft + nHeight - 2, lpcrCornerData[11]); } return; } BOOL __stdcall FLoadBack (int nIndexOfCard) { static int nIndexOfLastCard; //上次调用本函数时所要求的卡片序号 if (nIndexOfCard != nIndexOfLastCard) { MyDeleteHbm (hCustomBack); hCustomBack = LoadBitmap (hDllModule, LOWORD(nIndexOfCard)); nIndexOfLastCard = (hCustomBack == NULL? 0: nIndexOfCard); } return (nIndexOfLastCard != 0); } HBITMAP __fastcall _LoadCard (int nIndexOfCard) //参数通过eax传递 { static int nNumOfCardsLoaded; //已装入的卡片位图数目 static int nSearchIndex; //这个变量仅作为某种索引使用,无特别含义 int loc_nTransId; //为方便而设置的中间变量,等于所需的位图资源ID if (hCards[nIndexOfCard] == NULL) { if (nNumOfCardsLoaded >= 5) //已装入的卡片位图太多 { while (hCards[nSearchIndex] == NULL) //查找下一个不为空的卡片位图 { nSearchIndex = (nSearchIndex == 51? 0: nSearchIndex + 1); } DeleteObject (hCards[nSearchIndex]); --nNumOfCardsLoaded; //并删除之 hCards[nSearchIndex] = NULL; } //将卡片序号转换成位图资源ID loc_nTransId = (nIndexOfCard / 4) % 13 + (nIndexOfCard % 4) * 13 + 1; while ((hCards[nIndexOfCard] = LoadBitmap (hDllModule, LOWORD(loc_nTransId))) == NULL) { if (nNumOfCardsLoaded == 0) return NULL; //如果删完了所有已加载的位图,还是无法装入所要求的位图,则返回NULL while (hCards[nSearchIndex] == NULL) { nSearchIndex = (nSearchIndex == 51? 0: nSearchIndex + 1); } DeleteObject (hCards[nSearchIndex]); hCards[nSearchIndex] = NULL; --nNumOfCardsLoaded; } ++nNumOfCardsLoaded; } return hCards[nIndexOfCard]; }
代码: BOOL __stdcall cdtDraw (HDC hDC, int nXDest, int nYDest, int nIndexOfCard, DWORD dwDrawingOption, COLORREF crBackColor ) { return cdtDrawExt (hDC, nXDest, nYDest, nNormalWidth, nNormalHeight, nIndexOfCard, dwDrawingOption, crBackColor); }
代码: mov eax, A cmp eax, B jne @F ;do something @@:
代码: if (A == B){ //do something }
代码: mov eax, A cmp eax, B jne @F ;do something jmp _next ;注意这里多了一条jmp指令 @@: ;do else-thing _next:
代码: mov eax, A mov edx, C neg eax sbb eax, eax and eax, edx mov B, eax
代码: B = (A == 0? 0: C);
代码: mov eax, B test eax, eax mov A, eax jnz @F ;do something @@:
代码: if ((A = B) == 0){ //do something }
代码: mov eax, A mov ebx, B add eax, ebx mov A, eax
代码: regEax = A; regEbx = B; regEax += regEbx; A = regEax;
代码: A += B;
代码: push A call func_1 ;假设返回值在eax中 test eax, eax jz @F push eax call func_2 @@:
annodasm.asm 经分析和注释的反汇编文本
转载请注明来自看雪论坛 http://bbs.pediy.com/showthread.php?t=49531
版权声明:本文为博主原创文章,未经博主允许不得转载。
Windows XP 系统自带扑克牌资源动态链接库cards.dll逆向分析笔记
标签:
原文地址:http://blog.csdn.net/djd1234567/article/details/47402719