首页
社区
课程
招聘
[原创]用IDA Pro + OD 来分析扫雷 (2)
发表于: 2011-8-30 17:45 9734

[原创]用IDA Pro + OD 来分析扫雷 (2)

2011-8-30 17:45
9734
//之前小弟分析了扫雷的Main函数,这次小弟把它们逆向成C语言。
//扫雷的Main函数。以后我会陆续完善每一个函数。
//小弟就是想练习反汇编阅读的能力,因此自己记录这个
//逆向的过程,一是让自己有继续下去的理由,二是遇到问题
//可以向前辈请教。有不对的地方,欢迎各位赐教。

MineSweeper:

//这个是全局的。全局变量还有很多,我们稍后能看到,在InitGame或者AlsoInit函数里面都有描述。
//比如,雷数啊,雷区大小之类的。想深入了解的朋友可以看看。
HINSTACNE hInstance;

//Main函数
int WinMain(HINSTANCE hIns, int hPrevInstance, int CmdLine, HACCEL hAccelerate)
{
  hInstance = hIns;
  unsigned short error;
  
  WNDCLASSW WndClass; 
  struct tagMSG Msg; 
  struct tagINITCOMMONCONTROLSEX commonControl; 
  HACCEL hAcc; 

  InitGame(); //初始化一些东西,我们稍后会看到,从INI文件读。
  
  //这个dowrd_1005B38明显是个Flag, 也是个全局变量,我们先记下来。不过估计用处不大,先不管啦。  
  if (hAccelerate == 7 || hAccelerate == 2)
  {
    dowrd_1005B38 = 1;
  }
  else
  {
    dowrd_1005B38 = 0;
  }
  
  commonControl.dwICC = 5885;
  InitCommonControlsEx(&commonControl);
  HICON hIcon = (int)LoadIconW(hInstance, (LPCWSTR)0x64);
  WndClass.style = 0;
  WndClass.lpfnWndProc = (WNDPROC)WndProccess;
  WndClass.cbClsExtra = 0;
  WndClass.cbWndExtra = 0;
  WndClass.hInstance = hInstance;
  WndClass.hIcon = (HICON)hIcon;
  WndClass.hCursor = LoadCursorW(0, (LPCWSTR)0x7F00);
  WndClass.hbrBackground = GetStockObject(1);
  WndClass.lpszMenuName = 0;
  WndClass.lpszClassName = &AppName;
  
  //都是很熟悉的步骤,设置完就注册。
  if ( !RegisterClassW(&WndClass) )
  {  
    return 0;
  }
  
  //加载菜单和加速键
  hMenu = LoadMenuW(hInstance, (LPCWSTR)0x1F4);
  hAcc = LoadAcceleratorsW(hInstance, (LPCWSTR)0x1F5);
  
  //这个函数还是初始化一些数,从注册表里面读。
  AlsoInit();
  
  //创建了窗体。
  hWnd = CreateWindowExW(
           0,
           &AppName,
           &AppName,
           0xCA0000u,
           *(_DWORD *)&X - dword_1005A90,    //明显这2个全局变量是和坐标相关的。
           *(_DWORD *)&Y - dword_1005B88,
           dword_1005A90 + xRight,
           dword_1005B88 + yBottom,
           0,
           0,
           hInstance,
           0
  );

  if ( !hWnd )
  {
    error = 1000;
    PrintError(error);
    return 0;
  }
  
  //又一个函数。
  InitMenu(1);
  
  int ret = InitPictureAndBomb();
  
  if ( ret == 0)
  {
    error = 5;
    PrintError(error);
    return 0;
  }
  
  //这么多函数,以后都看看
  MenuFunc(dword_10056C4);
  SetBomb();
  
  //正常步骤。
  ShowWindow(hWnd, 1);
  UpdateWindow(hWnd);
  
  dword_1005B38 = 0;
  
  while ( GetMessageW(&Msg, 0, 0, 0) )
  {
    if ( !TranslateAcceleratorW(hWnd, hAcc, &Msg) )
    {
      TranslateMessage(&Msg);
      DispatchMessageW(&Msg);
    }
  }
  
  //清除内存。
  Clean();
  
  if ( dword_100515C != 0)
  {  
    //一会儿看看
    SetRegTable();
  }
  
  return 1;
}
其它函数,我们陆续分析,目标是逆向出扫雷源代码。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 236
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这个是InitGame函数:

int InitGame()
{
        unsigned __int16 seed;
        int result;
        int v2;
        HWND hWnd;
        HDC hDC;
        HDC hDC1;
        int v6;
        HWND hWnd1;
        DWORD dwDisposition;
       
        seed = GetTickCount();
        srand(seed);                //用时间当做随机种子
       
        //加载字符串
        LoadStringRes(1, (LPWSTR)&AppName, 32);     //程序名字
        LoadStringRes(7, (LPWSTR)&Seconds, 32);                //游戏耗时
        LoadStringRes(8, (LPWSTR)&PlayerName, 32);        //游戏者的名字
       
        //一些窗口的坐标
        CaptionHeight = GetSystemMetrics(4) + 1;
        MenuBarHeight = GetSystemMetrics(15) + 1;
        WindowBorderHeight = GetSystemMetrics(6) + 1;
        LeftTopX = GetSystemMetrics(5) + 1;

        //注册表的干活
        int ret = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\winmine", 0, 0, 0, 0x20019u, 0, &hKey, &dwDisposition);
       
        //
        v2 = GetParamFromReg(0x11u, 0, 0, 1);
        result = RegCloseKey(hKey);
       
        if ( ret != 0  || v2 == 0 )
        {
                uValue = ReadParamFromINI(2, 9, 9, 25);
                dword_10056AC = ReadParamFromINI(3, 9, 9, 30);
                LOWORD(dword_10056A0) = ReadParamFromINI(0, 0, 0, 3);
                dword_10056A4 = ReadParamFromINI(1, 10, 10, 999);
                *(_DWORD *)&X = ReadParamFromINI(4, 80, 0, 1024);
                *(_DWORD *)&Y = ReadParamFromINI(5, 80, 0, 1024);
                *(_DWORD *)&dword_10056B8 = ReadParamFromINI(6, 0, 0, 3);
                *(_DWORD *)&Data = ReadParamFromINI(7, 1, 0, 1);
                dword_10056C0 = ReadParamFromINI(9, 0, 0, 1);
                dword_10056C4 = ReadParamFromINI(8, 0, 0, 2);
                *(_DWORD *)&dword_10056CC = ReadParamFromINI(11, 999, 0, 999);
                *(_DWORD *)&dword_10056D0 = ReadParamFromINI(13, 999, 0, 999);
                *(_DWORD *)&dword_10056D4 = ReadParamFromINI(15, 999, 0, 999);
                GetProfileString(12, &String1);
                GetProfileString(14, &word_1005718);
                GetProfileString(16, &String);
               
                hWnd = GetDesktopWindow();
                hDC = GetDC(hWnd);
                hDC1 = hDC;
                v6 = GetDeviceCaps(hDC, 24);
                *(_DWORD *)&dword_10056C8 = ReadParamFromINI(10, v6 != 2, 0, 1);
                hWnd1 = GetDesktopWindow();
                ReleaseDC(hWnd1, hDC1);
                if ( *(_DWORD *)&dword_10056B8 == 3 )
                {       
                        *(_DWORD *)&dword_10056B8 = PlaySound();
                }
               
                result = SetRegTable();
        }
  return result;
}
2011-8-31 09:55
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
嗯。支持啊!!!!!!
2011-8-31 11:04
0
雪    币: 236
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
int LoadStringRes(unsigned __int16 uID, LPWSTR lpBuffer, int nBufferMax)
{
        int result;
        result = LoadStringW(hInstance, uID, lpBuffer, nBufferMax);

        if ( !result )
        {       
                result = PrintError(0x3E9u);
        }

        return result;
}
2011-9-2 13:45
0
雪    币: 236
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这个是AlsoInit()函数:

int AlsoInit(DWORD this)
{
        HWND hWnd1;
        HDC hDC;
        HDC hDC1;
        int v4;
        HWND hWnd2;
        DWORD dwDisposition;

        dwDisposition = this;
        RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\winmine", 0, 0, 0, 0x20019u, 0, &hKey, &dwDisposition);
        uValue = GetParamFromReg(2u, 9, 9, 25);
        ZoneY = uValue;
        dword_10056AC = GetParamFromReg(3u, 9, 9, 30);
        ZoneX = dword_10056AC;
        LOWORD(dword_10056A0) = GetParamFromReg(0, 0, 0, 3);
        dword_10056A4 = GetParamFromReg(1u, 10, 10, 999);
        *(_DWORD *)&X = GetParamFromReg(4u, 80, 0, 1024);
        *(_DWORD *)&Y = GetParamFromReg(5u, 80, 0, 1024);
        *(_DWORD *)&dword_10056B8 = GetParamFromReg(6u, 0, 0, 3);
        *(_DWORD *)&Data = GetParamFromReg(7u, 1, 0, 1);
        dword_10056C0 = GetParamFromReg(9u, 0, 0, 1);
        dword_10056C4 = GetParamFromReg(8u, 0, 0, 2);
        *(_DWORD *)&dword_10056CC = GetParamFromReg(0xBu, 999, 0, 999);
        *(_DWORD *)&dword_10056D0 = GetParamFromReg(0xDu, 999, 0, 999);
        *(_DWORD *)&dword_10056D4 = GetParamFromReg(0xFu, 999, 0, 999);
        GetValueFromReg(12, &String1);
        GetValueFromReg(14, &word_1005718);
        GetValueFromReg(16, &String);
       
        hWnd1 = GetDesktopWindow();
        hDC = GetDC(hWnd1);
        hDC1 = hDC;
        v4 = GetDeviceCaps(hDC, 24);
       
        *(_DWORD *)&dword_10056C8 = GetParamFromReg(0xAu, v4 != 2, 0, 1);
       
        hWnd2 = GetDesktopWindow();
        ReleaseDC(hWnd2, hDC1);
       
        if ( *(_DWORD *)&dword_10056B8 == 3 )
        {       
                *(_DWORD *)&dword_10056B8 = PlaySound();
        }
       
        return RegCloseKey(hKey);
}
2011-9-2 14:26
0
雪    币: 420
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
呵呵 ,顶上去
2011-9-2 14:29
0
雪    币: 108
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
很好狠强大啊
2011-9-2 15:24
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
8
很好很强大!
2011-9-2 18:51
0
雪    币: 175
活跃值: (2556)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习学习,IDA用的比较少。
2011-9-10 15:49
0
雪    币: 20
活跃值: (99)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
学习IDA中。。。
2011-9-21 22:37
0
游客
登录 | 注册 方可回帖
返回
//