我使用的是 OllyDbg 2.01,我通过本教程了解了调用 DLL 导出的工作原理。即使它是为另一个版本的 OllyDBG 编写的,它也能正常工作。我们应该注意到,在 USER32.dll 的例子中,OllyDBG 检测输入参数的数量,所以我可以从调用 DLL 导出对话框中更改它们。
我决定用 C++ 编写自己的 DLL 库,以便更详细地测试 OllyDBG 的功能。
这是我的图书馆的源代码。
CPPlib.h
#pragma once
#ifdef CPPLib_EXPORTS
#define CPPLib_API __declspec(dllexport)
#else
#define CPPLib_API __declspec(dllimport)
#endif
#include <string>
namespace CPPLib
{
class Functions
{
public:
static CPPLib_API void Identify();
static CPPLib_API void GetText();
static CPPLib_API void PrintText(std::string& s);
};
}
CPPLib.cpp
#include "stdafx.h"
#include "CPPLib.h"
#include <iostream>
#include <windows.h>
namespace CPPLib
{
void Functions::Identify()
{
std::cout << "This is a CPPlib \r\n";
}
void Functions::GetText()
{
std::cout << "This is a random text from CPPlib \r\n";
}
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
void Functions::PrintText(std::string& s)
{
std::wstring stemp = CPPLib::s2ws(s);
LPCWSTR result = stemp.c_str();
MessageBox(0, result, (LPCWSTR)L"MessageBox caption", MB_OK);
std::cout << "This is a user input text: " << s;
}
}
在这个问题中,我的兴趣在于函数PrintText。它将字符串作为输入参数,用它显示消息框并在控制台中打印相同的字符串。
如果我从 C++ 程序调用这个函数 - 它工作得很好。
#include "stdafx.h"
#include "CPPLib.h"
#include <string>
int main()
{
CPPLib::Functions::Identify();
CPPLib::Functions::GetText();
std::string s = "USER INPUT";
CPPLib::Functions::PrintText(s);
return 0;
}
与教程中的示例不同,OllyDBG 不会检测我的 DLL 的输入参数数量。
此外,即使我在调用该函数时手动定义它(例如选择 Arg1 作为内存缓冲区 1),它也不会采用我想要的参数。并且没有其他方法可以将这个参数更改为进入函数的步骤,找到它所引用的内存地址并在那里更改它。
所以我的问题是:为什么 OllyDbg 从 USER32.dll 检测函数中的输入参数数量(并允许轻松更改它们),而不是在我自己的 DLL 中?我怎样才能克服这个问题?




