<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [YU-RIS] 中文路徑無法運行

      [YU-RIS] 中文路徑無法運行

      0x00 背景

      今天發現個游戲 鯨神のティアスティラ

      一般來說yuris的游戲,雙擊是可以打開的,即使沒轉區,頂多也就亂碼嘛,但是這游戲還確定有點奇葩,雙擊打不開,轉區可以打開,然后把路徑全部換成英文也可以打開。這種情況BGI之前遇到過,BGI那個是MultiByteToWideChar的問題。

      這種打不開的情況是連窗口都出不來的,其實更多的游戲不轉區打不開的情況通常是腳本和文件讀取的編碼問題,就是游戲可以跑起來,但是會黑屏之類的。

      0x01 觀察

      我們用x64dbg運行一下游戲看看,發現游戲自己退出了。

      查看log窗口也沒發現什么異常,估計是調用了ExitProcess()函數來結束程序的

      ExitProcess()函數下個斷點,重新跑一下,發現確實斷下來了。為了方便跟蹤退出的原因,我們先用IDA分析一下游戲執行文件。

      我們先來到看看斷下來的地方,找到壓入棧里的返回地址(也就是來到調用 ExitProcess()函數的地方)也就是找到 call dword ptr ds:[&ExitProcess],復制一下地址,在IDA里按G轉到相應的地方,然后反編譯成C語言

      可以發現這個是在doexit這個函數里執行的,對doexit按x來查看誰調用了這個函數,有兩個結果,然后用x64dbg對他們下斷點,看看是誰調用的,重復該動作(注意觀察傳入函數的值),ExitProcess(uExitCode);反編譯后有IDA可以看到這個,uExitCode這個我們已經從x64dbg里可以看到是0,所以這也是一個關鍵是線索,往回追的時候要注意看這個變量什么時候變成了0。

        v5 = WinMain(ModuleHandleA, 0, lpCmdLine, v3);
        exit(v5);
      

      最終會來到這個地方,可以發現0其實是v5,也就是WinMain的返回值。

      現在進到WinMain里看看誰Return了0,配合x64dbg方便定位。

       hMutex = CreateMutexA(0, 0, lpMutexName);
        if ( hMutex )
        {
          if ( GetLastError() == 183 )
          {
            CloseHandle(hMutex);
            v6 = 1;
          }
          else
          {
            v6 = 0;
          }
        }
        else
        {
          v6 = -1;
        }
        if ( v6 )
        {
          sub_41194C();
          sub_411CFC();
          return 0;
        }
      

      最終可以發現,其實是WinMain里第二次調用CreateMutexA的時候出了問題,導致了程序退出。

      0x02 理解

      CreateMutexA是什么呢?你搜一下可以發現這個是創建互斥體的,哎,不懂也沒關系,其實你也不要管他干啥的,可以先看看它的返回值,判斷一下是什么問題導致這個函數執行失敗。

      在x64dbg里調試觀察該函數執行完畢收的eax的值,發現是0

      If the function succeeds, the return value is a handle to the newly created mutex object.
      
      If the function fails, the return value is NULL. To get extended error information, call GetLastError.
      

      MSDN里對返回值的描述是這樣的,叫我們調用GetLastError(),整好,下面就一個

      00403C52  | 33C0                        | xor eax,eax                                   |
      00403C54  | 68 C0606800                 | push kujira.6860C0                            |
      00403C59  | 50                          | push eax                                      |
      00403C5A  | 50                          | push eax                                      |
      00403C5B  | FF15 78F25800               | call dword ptr ds:[<&CreateMutexA>]           |
      00403C61  | A3 B4CC8300                 | mov dword ptr ds:[83CCB4],eax                 |
      00403C66  | 85C0                        | test eax,eax                                  |
      00403C68  | 0F84 7D020000               | je kujira.403EEB                              |
      00403C6E  | FF15 94F25800               | call dword ptr ds:[<&GetLastError>]           |
      00403C74  | 3D B7000000                 | cmp eax,B7                                    |
      00403C79  | 75 13                       | jne kujira.403C8E                             |
      00403C7B  | FF35 B4CC8300               | push dword ptr ds:[83CCB4]                    |
      00403C81  | FF15 7CF25800               | call dword ptr ds:[<&CloseHandle>]            |
      00403C87  | B8 01000000                 | mov eax,1                                     |
      00403C8C  | EB 02                       | jmp kujira.403C90                             |         |
      

      但是eax=0的時候并不會調用,所以我們可以改一下標志寄存器,或者把eax改成1之類的。

      EAX : 00000003
      EBX : 002DE000
      ECX : 00E50000
      EDX : 00E50000
      

      發現是3,可以用vs的tools欄里的error lookup查一下

      看樣子是說的路徑問題,但是這函數的參數好像也沒路徑吧

      HANDLE CreateMutexA(
        [in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes,
        [in]           BOOL                  bInitialOwner,
        [in, optional] LPCSTR                lpName
      );
      

      在x64dbg里看看 lpName這個東西是,發現看著還挺像路徑的,而且還是GBK編碼的

      c::users:dir-a:desktop:鯨神のティアスティラ\kujira.exe
      

      在MSDN看看這個參數的說明

      The remainder of the name can contain any character except the backslash character (\)
      

      他說這個參數里不能包含\這個字符,顯然這里可以看到,這玩意傳進來的參數里居然有\那肯定是不行了。我們先把這個反斜杠去掉看看,可以發現,這個函數成功執行過去了,返回值也是正常的,但是游戲還是退出了,后面應該還有問題。

      0x03 思索

      現在就有兩種思路了,繼續去跟蹤后面是什么問題導致了退出,或往前跟蹤看看是什么導致了這個問題,也就是第三個參數里有反斜杠。

      這里我選擇了第二種思路,然后我試著轉區運行了,這是可以打開的,然后觀察剛剛的地方,這次第三個參數的編碼是SJIS的了,并且沒有反斜杠。猜測一下問題可能就出在SJIS和GBK的編碼問題上。

      再到x64dbg看看CreateMutexA的第三個參數,可以看到這個直接push了一個具體的地址,應該是一個全局的變量,然后運行后把字符串寫了進來,我們直接對這個地址下硬件斷點,執行后就可以知道誰往這里寫了字符串了

      00411880  | 46                          | inc esi                                       |
      00411881  | 84D2                        | test dl,dl                                    |
      00411883  | 75 F6                       | jne kujira.41187B                             |
      00411885  | BA C0606800                 | mov edx,kujira.6860C0                         |
      0041188A  | 0FBE02                      | movsx eax,byte ptr ds:[edx]                   |
      0041188D  | 85C0                        | test eax,eax                                  |
      0041188F  | 74 27                       | je kujira.4118B8                              |
      00411891  | 0FB6F0                      | movzx esi,al                                  |
      00411894  | 0FB68E A0745B00             | movzx ecx,byte ptr ds:[esi+5B74A0]            |
      0041189B  | 41                          | inc ecx                                       |
      0041189C  | 0FBEF9                      | movsx edi,cl                                  | edi:":\\users\\dir-a\\desktop\\鯨神のティアスティラ\\kujira.exe"
      0041189F  | 83FF 02                     | cmp edi,2                                     | edi:":\\users\\dir-a\\desktop\\鯨神のティアスティラ\\kujira.exe"
      004118A2  | 0F84 8E000000               | je kujira.411936                              |
      004118A8  | 83F8 5C                     | cmp eax,5C                                    | 5C:'\\'
      004118AB  | 75 03                       | jne kujira.4118B0                             |
      004118AD  | C602 3A                     | mov byte ptr ds:[edx],3A                      | 3A:':'
      004118B0  | 42                          | inc edx                                       |
      

      可以發現是這個地方,可以看到有5C 3A的常數,看著像是把反斜杠替換成冒號,對這個地方進行跟蹤后發現,確實是這樣,但是有個地方的反斜杠沒換到,具體原因是這里

      movzx ecx, byte ptr ds:[esi+0x5B74A0]
      

      我們直接上IDA反編譯的代碼吧(我稍微對變量命名了一下)

        strcpy(lpMutexName, FullPath);
        iteString_ = lpMutexName;
        for ( iChar = lpMutexName[0]; *iteString_; iChar = *iteString_ )
        {
          if ( (SJIS_Range_Table[iChar] + 1) == 2 )
          {
            iteString_ += 2;
          }
          else
          {
            if ( iChar == 0x5C )
              *iteString_ = 0x3A;
            ++iteString_;
          }
        }
      

      0x5B74A0 這個地址其實是SJIS_Range_Table,也就是yuris常見的那個SJIS范圍檢查的表,沒想到這玩意居然會拿來檢查路徑,這個路徑是這樣獲取的

      GetModuleFileNameA(0, FullPath, 0x105u);
      

      獲取的路徑放到FullPath里,然后通過strcpy拷貝到lpMutexName里,拷貝完成后對這個路徑進行檢查,并把反斜杠替換成冒號,但是這東西并不是機械的掃描過去發現5C就干成3A的,如果路徑里有日文字符的話,SJIS編碼的第二位也有可能是5C,所以這玩意用SJIS的范圍校驗表來檢查字符串里的日文字符,并跳過。

      但是在中文區域的系統下,GetModuleFileNameA()獲取的是GBK編碼的字符,這就導致了它在檢查字符的時候出現了問題,把一些GBK編碼的字符當成了ASCII的單字節字符,而有些當成了雙字節字符,恰巧就出現了一個地方,前面的字節在SJIS內,后面剛好是0x5C,iteString_ += 2; 直接跳過了。如果全部范圍都不在SJIS里,其實也是可以的,就是機械的把這段字符串全部3A換成5C,至少CreateMutexA()這個函數執行不會出問題。

      0x04 解決

      好了,現在就很好辦了,直接把SJIS的這個范圍檢查表個改成GBK的就行了,這個以前說過了,這里就不多說了。

      posted @ 2024-03-26 16:23  Dir-A  閱讀(534)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 午夜免费无码福利视频麻豆| 久久久久无码国产精品不卡| 欧洲性开放老太大| 一区二区三区精品偷拍| 东京热一精品无码av| 久久美女夜夜骚骚免费视频| 欧美国产日产一区二区| 定陶县| 国产美女被遭强高潮免费一视频| 亚洲另类丝袜综合网| 加勒比中文字幕无码一区| 国产最新AV在线播放不卡| 丰满少妇呻吟高潮经历| 欧美日韩v| 免费无码又爽又刺激成人| 亚洲国产日韩a在线亚洲| 亚洲av片在线免费观看| 在线 欧美 中文 亚洲 精品| 国产精品成人亚洲一区二区| 国产成人综合在线女婷五月99播放| 人妻熟女一区无中文字幕| 久久久久香蕉国产线看观看伊 | 欧美日本激情| 伊人久久精品无码二区麻豆| 无码日韩做暖暖大全免费不卡| 亚洲另类无码一区二区三区| 日韩精品av一区二区三区| 人妻夜夜爽天天爽| 亚洲国产在一区二区三区| 国语对白做受xxxxx在线中国| 高清在线一区二区三区视频| 亚洲精品无码成人A片九色播放| 长治市| 国产办公室秘书无码精品99 | 亚洲国产欧美在线人成| 波多结野衣一区二区三区| 凤凰县| 99www久久综合久久爱com| 亚洲综合国产精品第一页| 农村欧美丰满熟妇xxxx| 色欲天天婬色婬香综合网|