国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

股票量化軟件:怎樣使用崩潰記錄來調(diào)試您的動(dòng)態(tài)鏈接庫(DLL)

2023-07-20 15:28 作者:大牛啊呢  | 我要投稿

現(xiàn)在讓我們看一下調(diào)用堆棧(call stack).

地址 77C36FA3 與堆棧頂部是一樣的. 這說明錯(cuò)誤發(fā)生在執(zhí)行memcpy函數(shù)時(shí), 正在把內(nèi)容從一塊內(nèi)存區(qū)域復(fù)制到另一區(qū)域. 在那里, 我們可以很確信地判定是否嘗試從地址為0的內(nèi)存區(qū)域復(fù)制數(shù)據(jù).
赫茲量化交易軟件
調(diào)用堆棧的第二行通知我們是哪一個(gè)函數(shù)使用了錯(cuò)誤的參數(shù)調(diào)用了memcpy函數(shù). 這是來自名為ExpertSample.dll的庫函數(shù)GetStringValue.
?

讓我們看一下這個(gè)函數(shù)的源代碼:

__declspec(dllexport) char* __stdcall GetStringValue(char *spar) ??{ ?? static char temp_string[256]; //---- ?? printf("GetStringValue takes \"%s\"\n",spar); ?? memcpy(temp_string,spar,sizeof(temp_string)-1); ?? temp_string[sizeof(temp_string)-1]=0; //---- ?? return(temp_string); ??}

我們可以看到, 在以上函數(shù)中, memcpy函數(shù)只調(diào)用了一次. 因?yàn)榈谝粋€(gè)參數(shù)指向已經(jīng)存在的內(nèi)存區(qū)域, 即被temp_string占用的變量, 我們可以確定是第二個(gè)參數(shù)出的錯(cuò). 確實(shí), 在提供的例子中沒有對(duì)變量是否為0做檢查. 加一行代碼 if(spar==NULL) 將會(huì)保護(hù)我們不會(huì)崩潰.

還有, 如果在函數(shù)中多次調(diào)用了memcpy函數(shù), 我們應(yīng)該怎么做呢?在我們的項(xiàng)目設(shè)置中, 讓我們?cè)O(shè)置輸出最詳細(xì)的編譯信息.

編輯

?

編輯



在重新構(gòu)建項(xiàng)目后, 我們會(huì)有一系列以.cod為擴(kuò)展名的文件, 它們分別對(duì)應(yīng)每一個(gè).cpp源文件. 我們現(xiàn)在感興趣的是ExpertSample. cod, 但是只有部分為GetStringValue函數(shù)獲得的代碼. 如下所示:

?GetStringValue@@YGPADPAD@Z PROC NEAR ? ? ? ? ? ; GetStringValue ; 70 ? : ? { ?00051 55 ? ? ? push ? ?ebp ?00052 8b ec ? ? ? ?mov ? ? ebp, esp ; 71 ? : ? ?static char temp_string[256]; ; 72 ? : //---- ; 73 ? : ? ?printf("GetStringValue takes \"%s\"\n",spar); ?00054 8b 45 08 ? ? mov ? ? eax, DWORD PTR _spar$[ebp] ?00057 50 ? ? ? push ? ?eax ?00058 68 00 00 00 00 ? push ? ?OFFSET FLAT:$SG19680 ?0005d ff 15 00 00 00 ? ?00 ? ? ? call ? ?DWORD PTR __imp__printf ?00063 83 c4 08 ? ? add ? ? esp, 8 ; 74 ? : ? ?memcpy(temp_string,spar,sizeof(temp_string)-1); ?00066 68 ff 00 00 00 ? push ? ?255 ? ? ? ? ? ?; 000000ffH ?0006b 8b 4d 08 ? ? mov ? ? ecx, DWORD PTR _spar$[ebp] ?0006e 51 ? ? ? push ? ?ecx ?0006f 68 00 00 00 00 ? push ? ?OFFSET FLAT:_?temp_string@?1??GetStringValue@@YGPADPAD@Z@4PADA ?00074 e8 00 00 00 00 ? call ? ?_memcpy ?00079 83 c4 0c ? ? add ? ? esp, ?12 ? ? ? ? ? ?; 0000000cH ; 75 ? : ? ?temp_string[sizeof(temp_string)-1]=0; ?0007c c6 05 ff 00 00 ? ?00 00 ? ? ? ?mov ? ? BYTE PTR _?temp_string@?1??GetStringValue@@YGPADPAD@Z@4PADA+255, 0 ; 76 ? : //---- ; 77 ? : ? ?return(temp_string); ?00083 b8 00 00 00 00 ? mov ? ? eax, OFFSET FLAT:_?temp_string@?1??GetStringValue@@YGPADPAD@Z@4PADA ; 78 ? : ? } ?00088 5d ? ? ? pop ? ? ebp ?00089 c2 04 00 ? ? ret ? ? 4 ?GetStringValue@@YGPADPAD@Z ENDP ? ? ? ? ? ?; GetStringValue

在調(diào)用堆棧第二行的數(shù)字10001051:0028 提供了GetStringValue 函數(shù)的內(nèi)部地址. 在函數(shù)位于調(diào)用堆棧上一行的代碼執(zhí)行過后, 控制將交到這一地址. 在目標(biāo)代碼中, GetStringValue函數(shù)從地址00051開始(要注意的是, 地址是16進(jìn)制的). 讓我們把這個(gè)值加上0028, 我們就得到了00079地址. 在此地址上, add esp,12 指令是符合緊跟在memcpy函數(shù)指令之后的. 我們已經(jīng)找到了執(zhí)行點(diǎn).
赫茲量化交易軟件

讓我們研究此實(shí)例, 錯(cuò)誤發(fā)生在輸入函數(shù)內(nèi)部開始的部位. 讓我們修改代碼:

__declspec(dllexport) char* __stdcall GetStringValue(char *spar) ??{ ?? static char temp_string[256]; //---- ?? printf("GetStringValue takes \"%s\"\n",spar); ?? for(int i=0; i<sizeof(temp_string)-1; i++) ???? { ??????temp_string[i]=spar[i]; ??????if(spar[i]==0) break; ???? } ?? temp_string[sizeof(temp_string)-1]=0; //---- ?? return(temp_string); ??}

我們已經(jīng)把memcpy函數(shù)調(diào)用替換成我們自己的按字節(jié)復(fù)制的循環(huán). 但是我們沒有使用對(duì)零的檢查, 這是為了創(chuàng)造一個(gè)錯(cuò)誤條件和錯(cuò)誤報(bào)告. 在新的報(bào)告中, 調(diào)用堆棧看起來有所不同:

Call stack ?:赫茲量化交易軟件 10001051:003A [1000108B] GetStringValue ? ? ? ? ? ? ? ? ? [C:\Program Files\MetaTrader 4\experts\libraries\ExpertSample.dll] 00452DD0:065E [0045342E] ?CallDllFunction@CExpertInterior 00459AC0:3B67 [0045D627] ?ExecuteStaticAsm@CExpertInterior 004505E0:010C [004506EC] ?RunExpertInt@CExpertInterior 7C80B357:01B4 [7C80B50B] GetModuleFileNameA ? ? ? ? ? ? ? [C:\WINDOWS\system32\kernel32.dll]

錯(cuò)誤發(fā)生于 GetStringValue 函數(shù)的 003A 地址. 讓我們看一下生成的列表.

?GetStringValue@@YGPADPAD@Z PROC NEAR ? ? ? ? ? ; 赫茲量化交易軟件GetStringValue ; 70 ? : ? { ?00051 55 ? ? ? push ? ?ebp ?00052 8b ec ? ? ? ?mov ? ? ebp, esp ?00054 51 ? ? ? push ? ?ecx ; 71 ? : ? ?static char temp_string[256]; ; 72 ? : //---- ; 73 ? : ? ?printf("GetStringValue takes \"%s\"\n",spar); ?00055 8b 45 08 ? ? mov ? ? eax, DWORD PTR _spar$[ebp] ?00058 50 ? ? ? push ? ?eax ?00059 68 00 00 00 00 ? push ? ?OFFSET FLAT:$SG19680 ?0005e ff 15 00 00 00 ? ?00 ? ? ? call ? ?DWORD PTR __imp__printf ?00064 83 c4 08 ? ? add ? ? esp, 8 ; 74 ? : ? ?for(int i=0; i<sizeof(temp_string)-1; i++) ?00067 c7 45 fc 00 00 ? ?00 00 ? ? ? ?mov ? ? DWORD PTR _i$[ebp], 0 ?0006e eb 09 ? ? ? ?jmp ? ? SHORT $L19682 $L19683: ?00070 8b 4d fc ? ? mov ? ? ecx, DWORD PTR _i$[ebp] ?00073 83 c1 01 ? ? add ? ? ecx, 1 ?00076 89 4d fc ? ? mov ? ? DWORD PTR _i$[ebp], ecx $L19682: ?00079 81 7d fc ff 00 ? ?00 00 ? ? ? ?cmp ? ? DWORD PTR _i$[ebp], 255 ? ?; 000000ffH ?00080 73 22 ? ? ? ?jae ? ? SHORT $L19684 ; 76 ? : ? ? ? temp_string[i]=spar[i]; ?00082 8b 55 08 ? ? mov ? ? edx, DWORD PTR _spar$[ebp] ?00085 03 55 fc ? ? add ? ? edx, DWORD PTR _i$[ebp] ?00088 8b 45 fc ? ? mov ? ? eax, DWORD PTR _i$[ebp] ?0008b 8a 0a ? ? ? ?mov ? ? cl, BYTE PTR [edx] ?0008d 88 88 00 00 00 ? ?00 ? ? ? mov ? ? BYTE PTR _?temp_string@?1??GetStringValue@@YGPADPAD@Z@4PADA[eax], cl ; 77 ? : ? ? ? if(spar[i]==0) break; ?00093 8b 55 08 ? ? mov ? ? edx, DWORD PTR _spar$[ebp] ?00096 03 55 fc ? ? add ? ? edx, DWORD PTR _i$[ebp] ?00099 0f be 02 ? ? movsx ? eax, BYTE PTR [edx] ?0009c 85 c0 ? ? ? ?test ? ?eax, eax ?0009e 75 02 ? ? ? ?jne ? ? SHORT $L19685 ?000a0 eb 02 ? ? ? ?jmp ? ? SHORT $L19684 $L19685: ; 78 ? : ? ? ?} ?000a2 eb cc ? ? ? ?jmp ? ? SHORT $L19683 $L19684: ; 79 ? : ? ?temp_string[sizeof(temp_string)-1]=0; ?000a4 c6 05 ff 00 00 ? ?00 00 ? ? ? ?mov ? ? BYTE PTR _?temp_string@?1??GetStringValue@@YGPADPAD@Z@4PADA+255, 0 ; 80 ? : //---- ; 81 ? : ? ?return(temp_string); ?000ab b8 00 00 00 00 ? mov ? ? eax, OFFSET FLAT:_?temp_string@?1??GetStringValue@@YGPADPAD@Z@4PADA ; 82 ? : ? } ?000b0 8b e5 ? ? ? ?mov ? ? esp, ebp ?000b2 5d ? ? ? pop ? ? ebp ?000b3 c2 04 00 ? ? ret ? ? 4 ?GetStringValue@@YGPADPAD@Z ENDP ? ? ? ? ? ?; GetStringValue

初始地址是相同的: 00051. 讓我們加上003A, 就得到了地址 0008B. 在這個(gè)地址上, 對(duì)應(yīng)的是 mov cl, BYTE PTR [edx] 指令. 讓我們看看報(bào)告中寄存器的內(nèi)容:

Registers ? : EAX=00000000 CS=001b EIP=1000108B EFLGS=00010246 ? ? ? ? ? ?: EBX=FFFFFFFF SS=0023 ESP=0259FAD4 EBP=0259FAD8 ? ? ? ? ? ?: ECX=77C318BF DS=0023 ESI=018ECD80 FS=003b ? ? ? ? ? ?: EDX=00000000 ES=0023 EDI=000000E8 GS=0000

是的, 當(dāng)然, EDX 寄存器內(nèi)容是0. 我們?cè)L問了進(jìn)程外的內(nèi)存并導(dǎo)致程序崩潰.
赫茲量化交易軟件

在最后, 我們有兩行如何對(duì)輸入?yún)?shù)傳入0參數(shù)值的代碼.

?? string null_string; ?? string sret=GetStringValue(null_string);

?


股票量化軟件:怎樣使用崩潰記錄來調(diào)試您的動(dòng)態(tài)鏈接庫(DLL)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
彩票| 翼城县| 措勤县| 双城市| 拜泉县| 黄冈市| 台州市| 衡南县| 奉新县| 米易县| 科尔| 平利县| 阳城县| 武安市| 拜泉县| 德庆县| 平原县| 托克托县| 闽清县| 海阳市| 丹江口市| 吉林市| 东港市| 调兵山市| 磐安县| 额尔古纳市| 兴山县| 大名县| 二连浩特市| 开化县| 潜山县| 滨海县| 泰宁县| 钦州市| 台湾省| 楚雄市| 鄢陵县| 丹棱县| 茌平县| 宜宾县| 成武县|