我正在使用Detours挂钩到可执行文件的消息函数,但我需要运行自己的代码然后调用原始代码.从我在Detours文档中看到的内容来看,这听起来应该是自动发生的.原始功能会在屏幕上显示一条消息,但是一旦我附上绕道,就会开始运行我的代码并停止打印.
原始功能代码大致是:
void CGuiObject::AppendMsgToBuffer(classA, unsigned long, unsigned long, int, classB);
Run Code Online (Sandbox Code Playgroud)
我的功能是:
void CGuiObject_AppendMsgToBuffer( [same params, with names] );
Run Code Online (Sandbox Code Playgroud)
我知道原始函数所在的内存位置,因此使用:
DWORD OrigPos = 0x0040592C;
DetourAttach( (void*)OrigPos, CGuiObject_AppendMsgToBuffer);
Run Code Online (Sandbox Code Playgroud)
让我进入这个功能.这段代码几乎完美无缺:用适当的参数调用我的函数.但是,执行会离开我的函数并且不会调用原始代码.我已经尝试过jmping,但是崩溃了程序(我假设代码Detours移动以适应钩子负责崩溃).
编辑:我已设法修复第一个问题,没有返回程序执行.通过将OrigPos值作为函数调用,我可以转到"trampoline"函数并从那里到原始代码.但是,在某些地方,寄存器正在发生变化,一旦我回到原始代码,就会导致程序崩溃并出现段错误.
Edit2:最终工作代码:
class CGuiObject
{
public:
void MyFunc( [params] );
};
DWORD TrueAddr = 0x0040592C;
CGuiObject::MyFunc( [params] )
{
_asm { pushad }
// process
_asm {
popad
leave
jmp TrueAddr
}
}
Run Code Online (Sandbox Code Playgroud)
并使用TrueAddr作为DetourAttach中的第一个参数.
我有一个程序,我正在添加全屏幕后处理效果.我没有该程序的源代码(它是专有的,虽然开发人员确实向我发送了调试符号的副本,.map格式).我有编写和工作的效果的代码,没有问题.
我现在的问题是将两者联系起来.
到目前为止我尝试了两种方法:
使用Detours修改原始程序的导入表.这很好用并且保证稳定,但是我所谈到的用户对它不满意,它需要安装(除了提取存档之外),并且如果使用Detours修补程序在条款下有效则存在一些问题EULA.那么,那个选择就出来了.
另一种选择是传统的DLL替换.我已经包装了OpenGL(opengl32.dll),我需要程序来加载我的DLL而不是系统副本(只需将它放在程序文件夹中,使用正确的名称,这很容易).
然后我需要我的DLL加载Cg框架和运行时(依赖于OpenGL)和其他一些东西.当Cg加载时,它调用我的一些函数,它调用Cg函数,我倾向于获得堆栈溢出和无限循环.我需要能够将Cg DLL包含在子目录中并仍然使用它们的函数(不确定是否可以将我的DLL导入表指向子目录中的DLL)或者我需要动态链接它们(我是d而不是做,只是为了简化构建过程),迫使他们引用系统的文件(而不是我的自定义替换).
整个链是:程序加载DLL A(名为opengl32.dll).DLL A加载Cg.dll并动态链接(GetProcAddress)到sysdir/opengl32.dll.我现在需要Cg.dll来引用sysdir/opengl32.dll,而不是 DLL A.
怎么做? 编辑:如果不使用GetProcAddress,如何轻松完成?如果没有其他工作,我愿意回到那个,但我不愿意,如果可能的话.
Edit2:我偶然发现了MSDN文档中的函数SetDllDirectory(完全不相关的搜索).乍一看,这看起来像我需要的.这是对的,还是我的错误判断?(关闭现在测试)
编辑3:我通过做一些不同的事情来解决这个问题.我没有删除OpenGL32.dll,而是将我的DLL重命名为DInput.dll.它不仅具有导出一个函数而不是超过120的优势(对于程序,Cg和GLEW),我不必担心运行的函数(我可以像往常一样链接到OpenGL) .为了进入我需要拦截的电话,我正在使用Detours.总而言之,它的效果要好得多.但是,这个问题仍然是一个有趣的问题(希望将来对其他任何试图做疯狂事情的人都有用).答案都很好,所以我不确定要选哪个...
我有一个相当大的代码库,它是高度模块化的(很多很多插件),并且经常需要在模块之间传递字符串等.供参考,代码:
现在,我的印象是,如果库或编译器versio发生更改,在模块之间传递STL对象确实会破坏.特别是当涉及到dtors并销毁模块/版本之外的对象时,它们就是在其中创建的.
MFC是否更安全?你能CString安全地将一个MFC对象(例如)从Base.dll传递给Plugin.dll吗?你必须传递一个指针,你不能安全地从插件中删除它吗?
MFC是否静态链接或从DLL使用是否重要?
MSDN在一些地方提到:
常规DLL中的所有内存分配都应保留在DLL中; DLL不应传递给调用可执行文件或从其接收以下任何一项:
- 指向MFC对象的指针
- 指向MFC分配的内存的指针
如果您需要执行上述任何操作,或者您需要在调用可执行文件和DLL之间传递MFC派生的对象,则必须构建扩展DLL.
但是,页面扩展DLL提到它们主要用于从MFC对象派生的实现对象.我没有兴趣这样做,只是使用它们并在各种模块之间传递.
传递shared_ptrs会改变任何东西(或带有虚拟dtor的类)吗?
如果没有诉诸C类型,是否有解决方案?
我正在尝试为.dll注入写一个.dll库.而且由于这个事实,它必须有一个名为DllMain的例程,因为这将被用作入口点.我认为我的问题可能源于这样一个事实,即我在一个静态库中进行链接,该库使用了afxmt.h中的线程和互斥锁.因为在某个地方,包含这个导致链接器从mfcs100ud.lib链接,mfcs100ud.lib显然包含自己的DllMain版本.
这是给我带来麻烦的文件:
dllmain.cpp
#include "stdafx.h"
#include <stdio.h>
#include "NamedPipeLogger.h"
static CNamedPipeLogger m_PipeLogger("Log.txt");
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
}
Run Code Online (Sandbox Code Playgroud)
这是dllmain.cpp包含的stdafx.h文件.
stdafx.h中
#pragma once
#define _AFXDLL
#include <Afx.h>
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
Run Code Online (Sandbox Code Playgroud)
这是我的错误消息:
错误32错误LNK2005:_DllMain @ 12已在dllmain.obj中定义D:\ xxxxx\xxxxx\xxxxxx\mfcs100ud.lib(dllmodul.obj)
我只是搞砸了,因为我不能将我的Dll入口点的名称更改为DllMain以外的其他名称?
我正在使用C#编写应用程序,需要从特定的数据文件格式进行读写.目前唯一的问题是格式使用严格的单字节字符,当我使用writer和char数组时,C#一直试图抛出Unicode(这会使文件大小增加一倍,以及其他严重的问题).我一直在努力修改代码以使用字节数组,但是在将它们提供给树视图和数据网格控件时会引起一些抱怨,并且它涉及转换等等.
我花了一点时间谷歌搜索,似乎没有一个简单的typedef我可以用来强制char类型使用字节为我的程序,至少不会没有造成额外的复杂性.
是否有一种简单的方法可以强制C#.NET程序仅使用ASCII而不接触Unicode?
后来,我得到了这个几乎工作.使用ASCIIEncoding的BinaryReader在/作家结束了固定的大多数问题(一些问题有一个多余的字符被前置到字符串发生,但我固定的了).我有一个最后一个问题,它很小但可能很大:在文件中,?当我加载/保存文件时,特定字符(打印为欧元符号)转换为a .这在文本中并不是一个问题,但如果它出现在记录长度上,它可能会改变大小千字节(显然不是很好).我认为它是由编码引起的,但如果它来自文件,为什么不回来呢?
确切的问题/结果如下:
原始文件:0x80(欧元)
编码:**ASCII:0x3F(?)**UTF8:0xC280(A-hat euro)
这些结果都不会起作用,因为文件中的任何位置都可以更改(如果在记录长度int中将80更改为3F,则可能是65*(256 ^ 3)的差异).不好.我尝试使用UTF-8编码,认为这样可以很好地解决问题,但它现在正在添加第二个字符,这更糟糕.
我需要将 C 和 C++ 函数解析和拆分为主要组件(返回类型、函数名称/类和方法、参数等)。
我正在使用标题或签名采用以下形式的列表:
公共:void __thiscall myClass::method(int, class myOtherClass * )
我有以下正则表达式,适用于大多数功能:
(?<expo>public\:|protected\:|private\:) (?<ret>(const )*(void|int|unsigned int|long|unsigned long|float|double|(class .*)|(enum .*))) (?<decl>__thiscall|__cdecl|__stdcall|__fastcall|__clrcall) (?<ns>.*)\:\:(?<class>(.*)((<.*>)*))\:\:(?<method>(.*)((<.*>)*))\((?<params>((.*(<.*>)?)(,)?)*)\)
Run Code Online (Sandbox Code Playgroud)
有一些函数它不喜欢解析,但似乎与模式匹配。我不担心目前不是类成员的匹配函数(可以稍后处理)。该表达式用于 C# 程序,因此<label>s 用于轻松检索组。
我想知道是否有一个标准的正则表达式来解析所有函数,或者如何改进我的来处理奇怪的异常?
在这篇博客文章中,有一句话如下:
此哈希对于给定文本是唯一的.如果再次对同一文本使用哈希函数,则会获得相同的哈希值.但是没有办法从哈希中获取给定的文本.
请原谅我对数学的无知,但我无法理解为什么不可能从哈希中获取给定的文本.
我会理解,如果我们使用一个密钥加密值而另一个密钥解密,但我无法在脑海中弄明白.幕后真的发生了什么?
任何让我清醒的事情都会受到赞赏.
我有一个程序(NWShader)挂钩到第二个程序的OpenGL调用(NWN)来做后处理效果和诸如此类的东西.
NWShader最初是为Windows构建的,通常是现代版本(win32),并使用DLL导出(让Windows加载它并获取一些OpenGL函数)和Detours(挂钩到其他函数).我正在使用Win在查看sysdir之前在当前目录中查找任何DLL的技巧,因此它会加载我的.我在DLL上使用此方法重定向:
#pragma comment(linker, "/export:oldFunc=nwshader.newFunc)
Run Code Online (Sandbox Code Playgroud)
将它们发送到我自己的DLL中的不同命名函数.然后我做任何处理并从系统DLL调用原始函数.
我需要将NWShader移植到Linux(NWN存在于两种版本中).据我所知,我需要做的是一个共享库(.so文件).如果这是在NWN可执行文件之前预加载的(我找到了一个shell脚本来处理它),我的函数将被调用.唯一的问题是我需要调用原始函数(我会使用各种DLL动态加载方法,我认为)并且需要能够像Detour一样进行内部函数挂钩.
目前我正在使用Ubuntu 9.10 x64(使用32位编译器标志).我无法在Google上找到太多帮助,但我不确切地知道*nix社区所指的是什么.我可以编写C++代码,但我更习惯于Windows.作为OpenGL,需要修改以与Linux兼容的唯一部分是挂钩代码和调用.有没有一种简单易行的方法,或者它是否涉及重新创建Detours并动态加载原始函数地址?
我有一个项目,其中包含一些相对不相交的页面,每个页面都包含自己的入口点脚本.这些脚本require使用commonjs语法很多其他脚本,需要通过6to5进行转换并由browserify捆绑.
我想设置一个gulp任务,捕获匹配模式的所有文件并将它们传递给bundler,但我不知道如何将文件传递gulp.src给browserify(filename).
我的gulpfile看起来像:
var gulp = require("gulp");
var browserify = require("browserify");
var to5browserify = require("6to5-browserify");
var source = require("vinyl-source-stream");
var BUNDLES = [
"build.js",
"export.js",
"main.js"
];
gulp.task("bundle", function () {
/* Old version, using glob:
return gulp.src("src/** /*.js")
.pipe(sixto5())
.pipe(gulp.dest("dist"));
*/
// New version, using array:
return BUNDLES.map(function (bundle) {
return browserify("./src/" + bundle, {debug: true})
.transform(to5browserify)
.bundle()
.pipe(source(bundle))
.pipe(gulp.dest("./dist"));
});
});
gulp.task("scripts", ["bundle"]);
gulp.task("html", function () {
return gulp.src("src/**/*.html")
.pipe(gulp.dest("dist"));
});
gulp.task("styles", …Run Code Online (Sandbox Code Playgroud) 我有一个包含AJAX请求的Bluebird承诺,需要在请求失败时拒绝承诺.我想提供为什么请求失败的原因,主要是从状态代码中提取到可能附加的任何catch块.为了实现这一点,我有UnauthorizedError和NotFoundError类似的类,都扩展Error到与Bluebird的模式匹配catch.
我不确定的部分是我应该throw还是调用拒绝处理程序.我的代码看起来像:
class Request {
// other methods
send(method, url, args, body) {
return new Promise((res, rej) => {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = () => {
res(JSON.parse(xhr.responseText));
};
xhr.onerror = () => {
let status = xhr.status;
switch (status) {
case 401:
// Should I use throw:
throw new UnauthorizedError(url);
// or
rej(new UnauthorizedError(url));
}
};
xhr.send();
});
}
}
Run Code Online (Sandbox Code Playgroud)