LoadLibrary加载dll 返回NULL,GetLastError=126

cokomowang 2016-02-15 11:36:18
大家新年好- -刚刚过完年又要开始调程序码代码了

如题,但是情况有点复杂

两个不同的工程,工程a和工程b,我自己在工程c中写了一个c.dll来给工程a和b调用,c.dll还依赖另外两个dll,一共三个dll都全部放到了两个工程的exe目录下

但是,在工程a中调用c.dll的函数成功;而在工程b中则无法成功加载,GetLastError=126。
可以肯定工程b的dll路径是绝对没有问题的,原因是我另外写了一个测试用的,不依赖任何其他dll 的一个dll(其中的函数只有return语句),在a和b中都被成功调用

我觉得问题还是出在c.dll缺少依赖上,但是不明白为何两个工程一个可以另一个不行,求解答啊TT

dependency walker打开c.dll的部分缺失项如下:

API-MS-WIN-CORE-APIQUERY-L1-1-0.DLL
API-MS-WIN-CORE-APPCOMPAT-L1-1-1.DLL
API-MS-WIN-CORE-APPINIT-L1-1-0.DLL
API-MS-WIN-CORE-ATOMS-L1-1-0.DLL
API-MS-WIN-CORE-COM-L1-1-0
API-MS-WIN-CORE-COM-L1-1-1.DLL
API-MS-WIN-CORE-COM-MIDLPROXYSTUB-L1-1-0.DLL
API-MS-WIN-CORE-COM-PRIVATE-L1-1-0.DLL
API-MS-WIN-CORE-COM-PRIVATE-L1-1-1.DLL
API-MS-WIN-CORE-COMM-L1-1-0.DLL
API-MS-WIN-CORE-CONSOLE-L1-1-0.DLL
API-MS-WIN-CORE-CONSOLE-L2-1-0.DLL
API-MS-WIN-CORE-CRT-L1-1-0.DLL
API-MS-WIN-CORE-CRT-L2-1-0.DLL
API-MS-WIN-CORE-DATETIME-L1-1-1.DLL
API-MS-WIN-CORE-DATETIME-L1-1-2.DLL
API-MS-WIN-CORE-DEBUG-L1-1-1.DLL
API-MS-WIN-CORE-DELAYLOAD-L1-1-1.DLL
API-MS-WIN-CORE-ENCLAVE-L1-1-0.DLL
API-MS-WIN-CORE-ERRORHANDLING-L1-1-1.DLL
API-MS-WIN-CORE-ERRORHANDLING-L1-1-3.DLL
API-MS-WIN-CORE-FIBERS-L1-1-1.DLL
API-MS-WIN-CORE-FIBERS-L2-1-1.DLL
API-MS-WIN-CORE-FILE-L1-2-1.DLL
API-MS-WIN-CORE-FILE-L1-2-2.DLL
API-MS-WIN-CORE-FILE-L2-1-1.DLL
API-MS-WIN-CORE-FILE-L2-1-2.DLL
API-MS-WIN-CORE-HANDLE-L1-1-0.DLL
API-MS-WIN-CORE-HEAP-L1-2-0.DLL
API-MS-WIN-CORE-HEAP-L2-1-0.DLL
API-MS-WIN-CORE-HEAP-OBSOLETE-L1-1-0.DLL
API-MS-WIN-CORE-INTERLOCKED-L1-2-0.DLL
API-MS-WIN-CORE-IO-L1-1-1.DLL
API-MS-WIN-CORE-JOB-L1-1-0.DLL
API-MS-WIN-CORE-JOB-L2-1-0.DLL
API-MS-WIN-CORE-KERNEL32-LEGACY-L1-1-1.DLL
API-MS-WIN-CORE-KERNEL32-LEGACY-L1-1-4.DLL
API-MS-WIN-CORE-KERNEL32-PRIVATE-L1-1-1.DLL
API-MS-WIN-CORE-KERNEL32-PRIVATE-L1-1-2.DLL
API-MS-WIN-CORE-LIBRARYLOADER-L1-2-0.DLL
API-MS-WIN-CORE-LIBRARYLOADER-L1-2-1.DLL
API-MS-WIN-CORE-LIBRARYLOADER-L2-1-0.DLL
API-MS-WIN-CORE-LOCALIZATION-L1-2-1.DLL
API-MS-WIN-CORE-LOCALIZATION-L1-2-2.DLL
API-MS-WIN-CORE-LOCALIZATION-L2-1-0.DLL
API-MS-WIN-CORE-LOCALIZATION-OBSOLETE-L1-3-0.DLL
API-MS-WIN-CORE-LOCALIZATION-PRIVATE-L1-1-0.DLL
API-MS-WIN-CORE-MEMORY-L1-1-2.DLL
API-MS-WIN-CORE-NAMEDPIPE-L1-2-0.DLL
API-MS-WIN-CORE-NAMEDPIPE-L1-2-2.DLL
API-MS-WIN-CORE-NAMESPACE-L1-1-0.DLL
API-MS-WIN-CORE-NORMALIZATION-L1-1-0.DLL
API-MS-WIN-CORE-PATH-L1-1-0.DLL
API-MS-WIN-CORE-PRIVATEPROFILE-L1-1-1.DLL
API-MS-WIN-CORE-PROCESSENVIRONMENT-L1-2-0.DLL
API-MS-WIN-CORE-PROCESSSNAPSHOT-L1-1-0.DLL
API-MS-WIN-CORE-PROCESSTHREADS-L1-1-1
API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL
API-MS-WIN-CORE-PROCESSTHREADS-L1-1-3.DLL
API-MS-WIN-CORE-PROCESSTOPOLOGY-L1-2-0.DLL
API-MS-WIN-CORE-PROFILE-L1-1-0.DLL
API-MS-WIN-CORE-PSAPI-ANSI-L1-1-0.DLL
API-MS-WIN-CORE-PSAPI-L1-1-0.DLL
API-MS-WIN-CORE-PSM-KEY-L1-1-0.DLL
API-MS-WIN-CORE-QUIRKS-L1-1-0.DLL
API-MS-WIN-CORE-REALTIME-L1-1-0.DLL
API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL
API-MS-WIN-CORE-REGISTRY-L1-1-1.DLL
API-MS-WIN-CORE-REGISTRYUSERSPECIFIC-L1-1-0.DLL
API-MS-WIN-CORE-RTLSUPPORT-L1-2-0.DLL
API-MS-WIN-CORE-SHLWAPI-LEGACY-L1-1-0.DLL
API-MS-WIN-CORE-SHLWAPI-OBSOLETE-L1-2-0.DLL
API-MS-WIN-CORE-SIDEBYSIDE-L1-1-0.DLL
API-MS-WIN-CORE-STRING-L1-1-0.DLL
API-MS-WIN-CORE-STRING-L2-1-0.DLL
API-MS-WIN-CORE-STRING-L2-1-1.DLL
API-MS-WIN-CORE-STRING-OBSOLETE-L1-1-0.DLL
API-MS-WIN-CORE-STRINGANSI-L1-1-0.DLL
API-MS-WIN-CORE-SYNCH-L1-1-0.DLL
API-MS-WIN-CORE-SYNCH-L1-2-0.DLL
API-MS-WIN-CORE-SYNCH-L1-2-1.DLL
API-MS-WIN-CORE-SYSINFO-L1-2-1.DLL
API-MS-WIN-CORE-SYSINFO-L1-2-3.DLL
API-MS-WIN-CORE-SYSTEMTOPOLOGY-L1-1-0.DLL
API-MS-WIN-CORE-THREADPOOL-L1-2-0.DLL
API-MS-WIN-CORE-THREADPOOL-LEGACY-L1-1-0.DLL
API-MS-WIN-CORE-THREADPOOL-PRIVATE-L1-1-0.DLL
API-MS-WIN-CORE-TIMEZONE-L1-1-0.DLL
API-MS-WIN-CORE-URL-L1-1-0.DLL
API-MS-WIN-CORE-UTIL-L1-1-0.DLL
API-MS-WIN-CORE-VERSION-L1-1-0.DLL
API-MS-WIN-CORE-VERSION-L1-1-1.DLL
API-MS-WIN-CORE-VERSION-PRIVATE-L1-1-0.DLL
API-MS-WIN-CORE-VERSIONANSI-L1-1-0.DLL
API-MS-WIN-CORE-VERSIONANSI-L1-1-1.DLL
API-MS-WIN-CORE-WINDOWSERRORREPORTING-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ERROR-L1-1-1.DLL
API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL
API-MS-WIN-CORE-WOW64-L1-1-0.DLL
API-MS-WIN-CORE-WOW64-L1-1-1.DLL
API-MS-WIN-CORE-XSTATE-L2-1-0.DLL
API-MS-WIN-DEVICES-CONFIG-L1-1-1.DLL
API-MS-WIN-EVENTING-CLASSICPROVIDER-L1-1-0.DLL
API-MS-WIN-EVENTING-PROVIDER-L1-1-0.DLL
API-MS-WIN-MM-JOYSTICK-L1-1-0.DLL
API-MS-WIN-MM-MISC-L1-1-1.DLL
API-MS-WIN-MM-MME-L1-1-0.DLL
API-MS-WIN-MM-TIME-L1-1-0.DLL
API-MS-WIN-SECURITY-APPCONTAINER-L1-1-0.DLL
API-MS-WIN-SECURITY-BASE-L1-2-0.DLL
API-MS-WIN-SECURITY-LSALOOKUP-L1-1-1.DLL
API-MS-WIN-SECURITY-LSAPOLICY-L1-1-0.DLL
API-MS-WIN-SECURITY-SDDL-L1-1-0.DLL
API-MS-WIN-SERVICE-MANAGEMENT-L1-1-0.DLL
API-MS-WIN-SERVICE-WINSVC-L1-2-0.DLL
API-MS-WIN-SHELL-SHELLCOM-L1-1-0.DLL
API-MS-WIN-SHELL-SHELLFOLDERS-L1-1-0.DLL
API-MS-WIN-STORAGE-EXPORTS-EXTERNAL-L1-1-0.DLL
API-MS-WIN-STORAGE-EXPORTS-INTERNAL-L1-1-0.DLL
SDL2_MIXER.DLL
API-MS-WIN-APPMODEL-IDENTITY-L1-2-0.DLL
API-MS-WIN-APPMODEL-RUNTIME-INTERNAL-L1-1-0.DLL
API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.DLL
API-MS-WIN-APPMODEL-RUNTIME-L1-1-1.DLL
API-MS-WIN-APPMODEL-STATE-L1-2-0.DLL
API-MS-WIN-APPMODEL-UNLOCK-L1-1-0.DLL
API-MS-WIN-BASE-UTIL-L1-1-0.DLL
API-MS-WIN-CORE-CALENDAR-L1-1-0.DLL
API-MS-WIN-CORE-COM-L2-1-1.DLL
API-MS-WIN-CORE-DEBUG-L1-1-0.DLL
API-MS-WIN-CORE-DELAYLOAD-L1-1-0.DLL
API-MS-WIN-CORE-ERRORHANDLING-L1-1-0.DLL
API-MS-WIN-CORE-FIBERS-L1-1-0.DLL
API-MS-WIN-CORE-FILE-L1-1-0.DLL
API-MS-WIN-CORE-FILE-L1-2-0.DLL
API-MS-WIN-CORE-FILE-L2-1-0.DLL
API-MS-WIN-CORE-HEAP-L1-1-0.DLL
API-MS-WIN-CORE-INTERLOCKED-L1-1-0.DLL
API-MS-WIN-CORE-IO-L1-1-0.DLL
API-MS-WIN-CORE-KERNEL32-LEGACY-L1-1-0.DLL
API-MS-WIN-CORE-LIBRARYLOADER-L1-1-0.DLL
API-MS-WIN-CORE-LOCALIZATION-L1-1-0.DLL
API-MS-WIN-CORE-LOCALIZATION-L1-2-0.DLL
API-MS-WIN-CORE-LOCALIZATION-OBSOLETE-L1-2-0.DLL
API-MS-WIN-CORE-LOCALREGISTRY-L1-1-0.DLL
API-MS-WIN-CORE-MARSHAL-L1-1-0.DLL
API-MS-WIN-CORE-MEMORY-L1-1-0.DLL
API-MS-WIN-CORE-MISC-L1-1-0.DLL
API-MS-WIN-CORE-PERFCOUNTERS-L1-1-0.DLL
API-MS-WIN-CORE-PROCESSENVIRONMENT-L1-1-0.DLL
API-MS-WIN-CORE-PROCESSTHREADS-L1-1-0.DLL
API-MS-WIN-CORE-PROCESSTHREADS-L1-1-1.DLL
API-MS-WIN-CORE-PROCESSTOPOLOGY-OBSOLETE-L1-1-0.DLL
API-MS-WIN-CORE-PSM-APPNOTIFY-L1-1-0.DLL
API-MS-WIN-CORE-REALTIME-L1-1-1.DLL
API-MS-WIN-CORE-REGISTRY-L2-2-0.DLL
API-MS-WIN-CORE-REGISTRY-PRIVATE-L1-1-0.DLL
API-MS-WIN-CORE-RTLSUPPORT-L1-1-0.DLL
API-MS-WIN-CORE-SHUTDOWN-L1-1-1.DLL
API-MS-WIN-CORE-SYSINFO-L1-1-0.DLL
API-MS-WIN-CORE-SYSINFO-L1-2-0.DLL
API-MS-WIN-CORE-TOOLHELP-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ERRORPRIVATE-L1-1-1.DLL
API-MS-WIN-CORE-WINRT-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-PROPERTYSETPRIVATE-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-PROPERTYSETPRIVATE-L1-1-1.DLL
API-MS-WIN-CORE-WINRT-REGISTRATION-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ROBUFFER-L1-1-0.DLL
API-MS-WIN-COREUI-SECRUNTIME-L1-1-0.DLL
API-MS-WIN-CRT-LOCALE-L1-1-0.DLL
API-MS-WIN-CRT-PRIVATE-L1-1-0.DLL
API-MS-WIN-CRT-RUNTIME-L1-1-0.DLL
API-MS-WIN-CRT-STRING-L1-1-0.DLL
API-MS-WIN-CRT-TIME-L1-1-0.DLL
API-MS-WIN-DEVICES-QUERY-L1-1-1.DLL
API-MS-WIN-DOWNLEVEL-ADVAPI32-L1-1-0.DLL
API-MS-WIN-DOWNLEVEL-ADVAPI32-L2-1-0.DLL
API-MS-WIN-DOWNLEVEL-KERNEL32-L2-1-0.DLL
API-MS-WIN-DOWNLEVEL-NORMALIZ-L1-1-0.DLL
API-MS-WIN-DOWNLEVEL-OLE32-L1-1-0.DLL
API-MS-WIN-DOWNLEVEL-SHELL32-L1-1-0.DLL
API-MS-WIN-DOWNLEVEL-SHLWAPI-L1-1-0.DLL
API-MS-WIN-DOWNLEVEL-SHLWAPI-L2-1-0.DLL
。。。。。。。。。


a.cpp

#include <stdio.h>
#include <Windows.h>
#include <tchar.h>

int main()
{
HMODULE hModule = NULL;
typedef int(*Func)();

hModule = LoadLibrary(_TEXT("..\\x64\\Release\\nMidiPlayer.dll"));
DWORD dw = GetLastError();
printf("%d\n", dw);

if (hModule){

Func fAdd = (Func)GetProcAddress(hModule, "MidiPlayerInit");
Func fAdd2 = (Func)GetProcAddress(hModule, "MidiPlayerRun");

printf("%d\n", fAdd());

printf("%d\n", fAdd2());
}
else{
printf("%d\n", -1);
}

system("pause");

return 0;
}


b.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "ppp.h"
#include "MyActor.h"
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>


// Sets default values
AMyActor::AMyActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;

}

void AMyActor::test()
{


}

void AMyActor::MidiPlayerInit()
{
HMODULE hModule = NULL;
typedef int(*Func)();

hModule = LoadLibrary(_TEXT("..\\..\\Plugins\\MyDLL\\nMidiPlayer.dll"));

int32 dw = GetLastError();
UE_LOG(LogTemp, Warning, TEXT("GetLastError info = %d"), dw);

Func fAdd = (Func)GetProcAddress(hModule, "MidiPlayerInit");
return;
}

void AMyActor::MidiPlayerRun()
{
HMODULE hModule = NULL;
typedef int(*Func)();

hModule = LoadLibrary(_TEXT("..\\..\\Plugins\\MyDLL\\nMidiPlayer.dll"));

int32 dw = GetLastError();
UE_LOG(LogTemp, Warning, TEXT("GetLastError info = %d"), dw);

Func fAdd = (Func)GetProcAddress(hModule, "MidiPlayerRun");
return;
}

// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();

}

// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);

}
...全文
1916 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-02-19
  • 打赏
  • 举报
回复
搜“dll hell”
cokomowang 2016-02-19
  • 打赏
  • 举报
回复
可还是有个问题,我的工程a在没加入缺失的那一部分dll 的情况下,仍然自始至终可以调用成功,然而工程b却非得加入那一部分dll才可以。。。并不是很明白- -
如图这是a,b的两个目录


我怀疑可能是包含和库路径相关的问题???
这是a,b的两个路径设置,但是他们的包含路径和库路径都是未修改的
其中b 工程是UE4定制的,只有这一页是路径设置

a的



b的



cokomowang 2016-02-19
  • 打赏
  • 举报
回复
引用 5 楼 zhoujielunzhimi 的回复:
模块路径错误。 通过VS运行和直接双击exe运行时,程序当前目录不一样,那么,你的c.dll的相对路径也不一样。 先试试绝对路径,看看是否成功?
引用 6 楼 CharlesSimonyi 的回复:
建议全部改成绝对路径进行一次测试以排除路径问题,相对路径容易受CurrentDirectory影响,如楼上所说,通过VS运行和直接双击exe运行时,由于CurrentDirectory的不同,像..\\..\\Plugins\\MyDLL\\nMidiPlayer.dll这样的相对路径意义是不同的,被调用的DLL的CurrentDirectory也会受宿主进程的影响而改变。
使用绝对路径后,通过vs运行和直接双击exe运行结果不一样的问题解决了,都调用dll 成功。这个问题就是相对路径引起的。 不过还有另一个问题没解决——工程b 中调用dll还是不成功,我再次排查依赖项的问题,最终解决。方法是将所引用的dll的所有配套的其他dll一起放入exe目录。工程b中调用成功。
赵4老师 2016-02-16
  • 打赏
  • 举报
回复
将除系统dll外的其它dll全部放在和exe相同目录下。
encoderlee 版主 2016-02-16
  • 打赏
  • 举报
回复
建议全部改成绝对路径进行一次测试以排除路径问题,相对路径容易受CurrentDirectory影响,如楼上所说,通过VS运行和直接双击exe运行时,由于CurrentDirectory的不同,像..\\..\\Plugins\\MyDLL\\nMidiPlayer.dll这样的相对路径意义是不同的,被调用的DLL的CurrentDirectory也会受宿主进程的影响而改变。
sumos 2016-02-16
  • 打赏
  • 举报
回复
模块路径错误。 通过VS运行和直接双击exe运行时,程序当前目录不一样,那么,你的c.dll的相对路径也不一样。 先试试绝对路径,看看是否成功?
fefe82 2016-02-15
  • 打赏
  • 举报
回复
在使用 GetLastError 之前,必须先确认真的有错误发生了。 对 LoadLibrary ,只有返回的 hModule 为 NULL 的时候,GetLastError 才有意义。 不检查 hModule 而直接检查 GetLastError 是没有意义的。
cokomowang 2016-02-15
  • 打赏
  • 举报
回复
UE_LOG是一个输出语句。。。。 可以忽略
幻夢之葉 2016-02-15
  • 打赏
  • 举报
回复
你两个不同路径的dll版本是否相同?debug就调用debug版本,release就调用release版本,32位64位要区别开来 还有该dll依赖的其他dll你是否也放置在\\Plugins\\MyDLL\\ 之下? 你测试是不是依赖项的问题,你可以在B工程中把路径修改为你A中的路径尝试下(注意exe跟dll编译版本要一致,调用的dll使用绝对路径以防止测试的时候路径错误)
cokomowang 2016-02-15
  • 打赏
  • 举报
回复
引用 2 楼 fefe82 的回复:
在使用 GetLastError 之前,必须先确认真的有错误发生了。 对 LoadLibrary ,只有返回的 hModule 为 NULL 的时候,GetLastError 才有意义。 不检查 hModule 而直接检查 GetLastError 是没有意义的。
其实原来代码就是你说的这样的= =只不过有些用于追踪的输出语句,为了让大家看着顺眼就删了但是没注意删多了。应该不是这个问题
你的程序加密过OD MD5值支持二次开发使用 防破解验证也可实现一机一码 VC++ 开发 STARTUPINFO startup; PROCESS_INFORMATION process; CString g_strCompanyName1 = ""; CString g_strCompanyName2 = ""; CString g_strCompanyName3 = ""; CString g_strCompanyName = "**"; BOOL CTaiShanApp::InitInstance() { AfxEnableControlContainer(); //#ifdef ZJH m_gMessageID = ::RegisterWindowMessage("WsSendMessageHqData"); CFileFind fnd; if(S_OK != ::CoInitialize (NULL)) return FALSE; // ReadDiskIDPartCwd(); // if(!FyRegister::IsValidUser()) // return FALSE; memset( &startup, 0, sizeof( startup ) ); startup.cb = sizeof( startup ); memset( &process, 0, sizeof( process ) ); if(fnd.FindFile ("WsSendMessageShare.exe")) { m_gbUseExe = true; } hAppMutex=::CreateMutex(NULL,TRUE,m_pszExeName); if(GetLastError() == ERROR_ALREADY_EXISTS) { CWnd *pPrevWnd = CWnd::GetDesktopWindow()->GetWindow(GW_CHILD); while(pPrevWnd) { if(::GetProp(pPrevWnd->GetSafeHwnd(),m_pszExeName)) { if(pPrevWnd->IsIconic()) pPrevWnd->ShowWindow(SW_RESTORE); pPrevWnd->SetForegroundWindow(); pPrevWnd->GetLastActivePopup()->SetForegroundWindow(); return false; } pPrevWnd = pPrevWnd->GetWindow(GW_HWNDNEXT); } return false; } //#endif #ifndef _NET_AUTHEN HMODULE hModule; hModule = LoadLibrary("ide21201.dll"); if (hModule==NULL) { AfxMessageBox("Can't find ide21201.dll"); return FALSE; } char *(WINAPI * GetIdeSerial)(); GetIdeSerial = (char *(WINAPI *)())GetProcAddress(hModule, "GetIdeSerial"); if (GetIdeSerial==NULL) { AfxMessageBox("Can't find GetIdeSerial in ide21201.dll"); return FALSE; } CString strSerialNumber;// = SERIAL_NUMBER; strSerialNumber = GetIdeSerial(); strSerialNumber.TrimLeft(" "); if (strSerialNumber.Compare(SERIAL_NUMBER)!=0) { AfxMessageBox("序列号错误"); return FALSE; } #else CDlgLogin dlgLogin; int nResponse = dlgLogin.DoModal(); if (nResponse!=1) return FALSE; #endif /* CDialogShowInformation dlg; dlg.DoModal();*/ int nResult; m_bAppAuthorized=TRUE; // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. CTaiTestSplash *m_splash; BOOL SplashOpen=FALSE; m_splash = new CTaiTestSplash; SplashOpen=m_splash->Create(); if( SplashOpen ) m_splash->ShowWindow(SW_SHOW); DWORD Currenttime=GetTickCount(); BeginWaitCursor(); #ifdef TEST_USER1 t = CTime::GetCurrentTime(); CTime t2 = g_timeUseEnd; if(t >= t2) { // AfxMessageBox("试用期已过,若想继续使用,请购买正式版!",MB_OK | MB_ICONSTOP); return false; } else 以上为部分代码
/****************************************************************************************/ /* Compiler.cpp */ /* */ /* Author: Jim Mischel */ /* Description: Dialog and thread code for compiling maps with gbsplib */ /* */ /* The contents of this file are subject to the Genesis3D Public License */ /* Version 1.01 (the "License"); you may not use this file except in */ /* compliance with the License. You may obtain a copy of the License at */ /* http://www.genesis3d.com */ /* */ /* Software distributed under the License is distributed on an "AS IS" */ /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ /* the License for the specific language governing rights and limitations */ /* under the License. */ /* */ /* The Original Code is Genesis3D, released March 25, 1999. */ /* Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved */ /* */ /****************************************************************************************/ #include "stdafx.h" #include "compiler.h" #pragma warning(disable : 4201 4214 4115 4514 4711) #include #include #pragma warning(default : 4201 4214 4115) #include #include #include #include "filepath.h" #include "consoletab.h" // for ConPrintf (yes, it's ugly) #include "util.h" static CWinThread *CompilerThread = NULL; static HWND hwndThreadParent = NULL; static geBoolean ThreadActive = GE_FALSE; static HINSTANCE GBSPHandle = NULL; static GBSP_FuncHook *GlobalFHook; static ofstream *CompileLog; CompilerErrorEnum Compiler_RunPreview ( char const *PreviewFilename, char const *MotionFilename, char const *GPreviewPath ) { assert (ThreadActive == GE_FALSE); char DestBspName[_MAX_PATH]; { // Verify the .BSP file exists... if (_access (PreviewFilename, 0) != 0) { return COMPILER_ERROR_NOBSP; } } // we're going to copy the preview file to the "levels" subdirectory // of the GPreviewPath directory... // // So, if the PreviewFilename is "C:\MyStuff\MyLevel.bsp", // and GPreviewPath is "C:\Editor\GPreview.exe", then the resulting // file name is "C:\Editor\levels\MyLevel.bsp" // { /* char PreviewDrive[_MAX_PATH]; char PreviewDir[_MAX_PATH]; char Name[_MAX_PATH]; char Ext[_MAX_PATH]; _splitpath (PreviewFilename, NULL, NULL, Name, Ext); _splitpath (GPreviewPath, PreviewDrive, PreviewDir, NULL, NULL); strcat (PreviewDir, "media\\levels\\"); _makepath (DestBspName, PreviewDrive, PreviewDir, Name, Ext); */ // make dest path same as source path strcpy(DestBspName, PreviewFilename); } // if source and destination are the same, then don't copy... if (stricmp (DestBspName, PreviewFilename) != 0) { if(!CopyFile (PreviewFilename, DestBspName, FALSE)) { int LastError; LastError = GetLastError(); if (LastError != ERROR_FILE_EXISTS) { ConPrintf("GPreviewPath: %s \n", GPreviewPath); ConPrintf("CopyFile (%s, %s)\nGetLastError()==%d\n", PreviewFilename, DestBspName, LastError); return COMPILER_ERROR_BSPCOPY; } } } { // copy the motion file if it exists char DestName[_MAX_PATH]; // check to see if the file exists FilePath_SetExt (DestBspName, ".mot", DestName); if (_access (MotionFilename, 0) == 0) // _access returns 0 on success...of course! { if (stricmp (MotionFilename, DestName) != 0) { if (!CopyFile (MotionFilename, DestName, FALSE)) { if(GetLastError() != ERROR_FILE_EXISTS) { ConPrintf ("%s", "Unable to copy the motion file.\n"); ConPrintf ("%s", "Continuing with preview.\n"); } } } } else { _unlink (DestName); } } { SHELLEXECUTEINFO shx; char Params[_MAX_PATH]; char DefaultDir[_MAX_PATH]; char NoExtName[_MAX_PATH]; FilePath_GetDriveAndDir (GPreviewPath, DefaultDir); FilePath_GetName (DestBspName, NoExtName); sprintf (Params, "-map %s", NoExtName); shx.fMask = 0; shx.hwnd = NULL; //(HWND)AfxGetMainWnd(); shx.lpVerb = NULL; shx.lpFile = GPreviewPath; shx.lpParameters= Params; shx.lpDirectory = DefaultDir; shx.nShow = SW_NORMAL; shx.hInstApp = NULL; shx.cbSize = sizeof(shx); ShellExecuteEx(&shx;); } return COMPILER_ERROR_NONE; } geBoolean Compiler_CancelCompile ( void ) { if (!ThreadActive) { return GE_FALSE; } return GlobalFHook->GBSP_Cancel (); } static CompilerErrorEnum Compiler_LoadCompilerDLL ( GBSP_FuncHook **ppFHook, HINSTANCE *pHandle, ERROR_CB ErrorCallbackFcn, PRINTF_CB PrintfCallbackFcn ) { GBSP_INIT *GBSP_Init; GBSP_Hook Hook; GBSP_FuncHook *FHook; assert (ppFHook != NULL); assert (pHandle != NULL); *ppFHook = NULL; Hook.Error = ErrorCallbackFcn; Hook.Printf = PrintfCallbackFcn; GBSPHandle = LoadLibrary("gbsplib.dll"); if (GBSPHandle == NULL) { PrintfCallbackFcn ("Compile Failed: Unable to load gbsplib.dll!\nGetLastError returned %d.\n", GetLastError ()); return COMPILER_ERROR_NODLL; } GBSP_Init =(GBSP_INIT*)GetProcAddress(GBSPHandle, "GBSP_Init"); if (GBSP_Init == NULL) { PrintfCallbackFcn ("%s", "Compile Failed: Couldn't initialize GBSP_Init, GBSPLib.Dll.\n."); FreeLibrary(GBSPHandle); return COMPILER_ERROR_MISSINGFUNC; } FHook = GBSP_Init (&Hook;); if (FHook == NULL) { PrintfCallbackFcn ("%s", "Compile Failed: GBSP_Init returned NULL Hook!, GBSPLib.Dll.\n."); FreeLibrary(GBSPHandle); return COMPILER_ERROR_MISSINGFUNC; } if(FHook->VersionMajor > GBSP_VERSION_MAJOR) { PrintfCallbackFcn ("%s", "Compile Failed: GBSP Version Incompatible, GBSPLib.Dll.\n."); FreeLibrary (GBSPHandle); return COMPILER_ERROR_MISSINGFUNC; } *ppFHook = FHook; *pHandle = GBSPHandle; return COMPILER_ERROR_NONE; } CompilerErrorEnum Compiler_Compile ( CompileParamsType const *pParams, ERROR_CB ErrorCallbackFcn, PRINTF_CB PrintfCallbackFcn ) { HINSTANCE GBSPHandle; CompilerErrorEnum CompileRslt; GBSP_RETVAL GbspRslt; char BspFilename[_MAX_PATH]; char MotionFilename[_MAX_PATH]; // load compiler DLL CompileRslt = Compiler_LoadCompilerDLL (&GlobalFHook;, &GBSPHandle;, ErrorCallbackFcn, PrintfCallbackFcn); if (CompileRslt == COMPILER_ERROR_NONE) { FilePath_SetExt (pParams->Filename, ".bsp", BspFilename); FilePath_SetExt (pParams->Filename, ".mot", MotionFilename); if (pParams->EntitiesOnly) { #if 1 #pragma message ("Should UpdateEntities return a GBSP_RETVAL?") if (GlobalFHook->GBSP_UpdateEntities ((char *)pParams->Filename, BspFilename)) { GbspRslt = GBSP_OK; } else { GbspRslt = GBSP_ERROR; } #else GbspRslt = GlobalFHook->GBSP_UpdateEntities ((char *)pParams->Filename, BspFilename); #endif switch (GbspRslt) { case GBSP_ERROR: PrintfCallbackFcn ("%s", "Compile Failed: GBSP_UpdateEntities returned an error. GBSPLib.Dll.\n"); CompileRslt = COMPILER_ERROR_BSPFAIL; break; case GBSP_OK : break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "UpdateEntities cancelled by user.\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; default : assert (0); } } else if (pParams->RunBsp) { _unlink (MotionFilename); // gotta make sure this doesn't exist... GbspRslt = GlobalFHook->GBSP_CreateBSP ((char *)pParams->Filename, (BspParms *)&pParams;->Bsp); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("%s", "Compile Failed: GBSP_CreateBSP encountered an error, GBSPLib.Dll.\n."); CompileRslt = COMPILER_ERROR_BSPFAIL; break; case GBSP_OK : //save as a bsp GbspRslt = GlobalFHook->GBSP_SaveGBSPFile(BspFilename); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("Compile Failed: GBSP_SaveGBSPFile for file: %s, GBSPLib.Dll.\n.", BspFilename); CompileRslt = COMPILER_ERROR_BSPSAVE; break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "Save cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; case GBSP_OK : break; default : assert (0); } break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "Compile cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; default : assert (0); //?? } GlobalFHook->GBSP_FreeBSP(); } } if (CompileRslt == COMPILER_ERROR_NONE) { if(pParams->DoVis && !pParams->EntitiesOnly) { GbspRslt = GlobalFHook->GBSP_VisGBSPFile ((char *)BspFilename, (VisParms *)&pParams;->Vis); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("Warning: GBSP_VisGBSPFile failed for file: %s, GBSPLib.Dll.\n.", BspFilename); break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "GBSP_VisGBPSFile cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; case GBSP_OK : break; default : assert (0); } } } if (CompileRslt == COMPILER_ERROR_NONE) { if (pParams->DoLight) { /* The compiler has no flag that tells it not to do min lighting. So, if the min lighting flag is not on, we set the MinLight vector to all 0s. */ LightParms rad; rad = pParams->Light; if (!pParams->UseMinLight) { geVec3d_Set (&rad;.MinLight, 0.0f, 0.0f, 0.0f); } // If UseMinLight isn't on, then don't pass GbspRslt = GlobalFHook->GBSP_LightGBSPFile(BspFilename, &rad;); switch (GbspRslt) { case GBSP_ERROR : PrintfCallbackFcn ("Warning: GBSP_LightGBSPFile failed for file: %s, GBSPLib.Dll.\n", BspFilename); break; case GBSP_CANCEL : PrintfCallbackFcn ("%s", "GBSP_LightGBSPFile cancelled by user\n"); CompileRslt = COMPILER_ERROR_USERCANCEL; break; case GBSP_OK : break; default : assert (0); } } } // and free the DLL... if (GBSPHandle != NULL) { FreeLibrary (GBSPHandle); } return CompileRslt; } static void Compiler_NotifyApp ( char const *buf, int MsgId ) { #if 1 char *errmsg; errmsg = Util_Strdup (buf); if (errmsg != NULL) { ::PostMessage (hwndThreadParent, MsgId, COMPILER_PROCESSID, (LPARAM)errmsg); } #else ConPrintf ("%s", buf); #endif } static void Compiler_PrintfCallback ( char *format, ... ) { va_list argptr; char buf[32768]; //this is ... cautious va_start (argptr, format); vsprintf (buf, format, argptr); va_end (argptr); if (CompileLog) (*CompileLog) << buf; Compiler_NotifyApp (buf, WM_USER_COMPILE_MSG); } static void Compiler_ErrorCallback ( char *format, ... ) { va_list argptr; char buf[32768]; //this is ... cautious va_start (argptr, format); vsprintf (buf, format, argptr); va_end (argptr); if (CompileLog) (*CompileLog) << buf; Compiler_NotifyApp (buf, WM_USER_COMPILE_ERR); } static UINT Compiler_ThreadProc ( void *pParam ) { CompileParamsType CompileParams; CompilerErrorEnum CompileRslt; assert (pParam != NULL); assert (ThreadActive == GE_FALSE); ThreadActive = GE_TRUE; CompileParams = *((CompileParamsType *)pParam); char LogFilename[_MAX_PATH]; FilePath_SetExt(CompileParams.Filename, ".log", LogFilename); CompileLog = new ofstream(LogFilename, ofstream::out | ofstream::trunc); CompileRslt = Compiler_Compile (&CompileParams;, Compiler_ErrorCallback, Compiler_PrintfCallback); if (CompileRslt == COMPILER_ERROR_NONE) { Compiler_PrintfCallback ("%s", "------------------------------\n"); Compiler_PrintfCallback ("%s", "Compile successfully completed\n"); } if (CompileLog) { (*CompileLog).close(); delete CompileLog; } // notify parent that the compile has completed ::PostMessage (hwndThreadParent, WM_USER_COMPILE_DONE, COMPILER_PROCESSID, (LPARAM)CompileRslt); ThreadActive = GE_FALSE; return 0; } CompilerErrorEnum Compiler_StartThreadedCompile ( CompileParamsType const *pParams, HWND hwndNotify ) { CWinThread *Thread; assert (ThreadActive == GE_FALSE); hwndThreadParent = hwndNotify; Thread = AfxBeginThread ( Compiler_ThreadProc, // AFX_THREADPROC pfnThreadProc, (LPVOID)pParams, // LPVOID pParam, THREAD_PRIORITY_NORMAL, // int nPriority = THREAD_PRIORITY_NORMAL, 0, // UINT nStackSize = 0, 0, // DWORD dwCreateFlags = 0, NULL // LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); if (Thread != NULL) { CompilerThread = Thread; return COMPILER_ERROR_NONE; } else { return COMPILER_ERROR_THREAD; // couldn't spawn the thread } } geBoolean Compiler_CompileInProgress ( void ) { return ThreadActive; }
Detours是微软开发的一个函数库, 用于修改运行中的程序在内存中的影像,从而即使没有源代码也能改变程序的行为。具体用途是: 拦截WIN32 API调用,将其引导到自己的子程序,从而实现WIN32 API的定制。 为一个已在运行的进程创建一新线程,装入自己的代码并运行。 ---- 本文将简介Detours的原理,Detours库函数的用法, 并利用Detours库函数在Windows NT上编写了一个程序,该程序能使有“调试程序”的用户权限的用户成为系统管理员,附录利用Detours库函数修改该程序使普通用户即可成为系统管理员 (在NT4 SP3上)。 一. Detours的原理 ---- 1. WIN32进程的内存管理 ---- 总所周知,WINDOWS NT实现了虚拟存储器,每一WIN32进程拥有4GB的虚存空间, 关于WIN32进程的虚存结构及其操作的具体细节请参阅WIN32 API手册, 以下仅指出与Detours相关的几点: ---- (1) 进程要执行的指令也放在虚存空间中 ---- (2) 可以使用QueryProtectEx函数把存放指令的页面的权限更改为可读可写可执行,再改写其内容,从而修改正在运行的程序 ---- (3) 可以使用VirtualAllocEx从一个进程为另一正运行的进程分配虚存,再使用 QueryProtectEx函数把页面的权限更改为可读可写可执行,并把要执行的指令以二进制机器码的形式写入,从而为一个正在运行的进程注入任意的代码 ---- 2. 拦截WIN32 API的原理 ---- Detours定义了三个概念: ---- (1) Target函数:要拦截的函数,通常为Windows的API。 ---- (2) Trampoline函数:Target函数的复制品。因为Detours将会改写Target函数,所以先把Target函数复制保存好,一方面仍然保存Target函数的过程调用语义,另一方面便于以后的恢复。 ---- (3) Detour 函数:用来替代Target函数的函数。 ---- Detours在Target函数的开头加入JMP Address_of_ Detour_ Function指令(共5个字节)把对Target函数的调用引导到自己的Detour函数, 把Target函数的开头的5个字节加上JMP Address_of_ Target _ Function+5作为Trampoline函数。例子如下: 拦截前:Target _ Function: ;Target函数入口,以下为假想的常见的子程序入口代码 push ebp mov ebp, esp push eax push ebx Trampoline: ;以下是Target函数的继续部分 …… 拦截后: Target _ Function: jmp Detour_Function Trampoline: ;以下是Target函数的继续部分 …… Trampoline_Function: ; Trampoline函数入口, 开头的5个字节与Target函数相同 push ebp mov ebp, esp push eax push ebx ;跳回去继续执行Target函数 jmp Target_Function+5 ---- 3. 为一个已在运行的进程装入一个DLL ---- 以下是其步骤: ---- (1) 创建一个ThreadFuction,内容仅是调用LoadLibrary。 ---- (2) 用VirtualAllocEx为一个已在运行的进程分配一片虚存,并把权限更改为可读可写可执行。 ---- (3) 把ThreadFuction的二进制机器码写入这片虚存。 ---- (4) 用CreateRemoteThread在该进程上创建一个线程,传入前面分配的虚存的起始地址作为线程函数的地址,即可为一个已在运行的进程装入一个DLL。通过DllMain 即可在一个已在运行的进程中运行自己的代码。 二. Detours库函数的用法 ---- 因为Detours软件包并没有附带帮助文件,以下接口仅从剖析源代码得出。 ---- 1. PBYTE WINAPI DetourFindFunction(PCHAR pszModule, PCHAR pszFunction) ---- 功能:从一DLL中找出一函数的入口地址 ---- 参数:pszModule是DLL名,pszFun
Detours是微软开发的一个函数库, 用于修改运行中的程序在内存中的影像,从而即使没有源代码也能改变程序的行为。具体用途是: 拦截WIN32 API调用,将其引导到自己的子程序,从而实现WIN32 API的定制。 为一个已在运行的进程创建一新线程,装入自己的代码并运行。 ---- 本文将简介Detours的原理,Detours库函数的用法, 并利用Detours库函数在Windows NT上编写了一个程序,该程序能使有“调试程序”的用户权限的用户成为系统管理员,附录利用Detours库函数修改该程序使普通用户即可成为系统管理员 (在NT4 SP3上)。 一. Detours的原理 ---- 1. WIN32进程的内存管理 ---- 总所周知,WINDOWS NT实现了虚拟存储器,每一WIN32进程拥有4GB的虚存空间, 关于WIN32进程的虚存结构及其操作的具体细节请参阅WIN32 API手册, 以下仅指出与Detours相关的几点: ---- (1) 进程要执行的指令也放在虚存空间中 ---- (2) 可以使用QueryProtectEx函数把存放指令的页面的权限更改为可读可写可执行,再改写其内容,从而修改正在运行的程序 ---- (3) 可以使用VirtualAllocEx从一个进程为另一正运行的进程分配虚存,再使用 QueryProtectEx函数把页面的权限更改为可读可写可执行,并把要执行的指令以二进制机器码的形式写入,从而为一个正在运行的进程注入任意的代码 ---- 2. 拦截WIN32 API的原理 ---- Detours定义了三个概念: ---- (1) Target函数:要拦截的函数,通常为Windows的API。 ---- (2) Trampoline函数:Target函数的复制品。因为Detours将会改写Target函数,所以先把Target函数复制保存好,一方面仍然保存Target函数的过程调用语义,另一方面便于以后的恢复。 ---- (3) Detour 函数:用来替代Target函数的函数。 ---- Detours在Target函数的开头加入JMP Address_of_ Detour_ Function指令(共5个字节)把对Target函数的调用引导到自己的Detour函数, 把Target函数的开头的5个字节加上JMP Address_of_ Target _ Function+5作为Trampoline函数。例子如下: 拦截前:Target _ Function: ;Target函数入口,以下为假想的常见的子程序入口代码 push ebp mov ebp, esp push eax push ebx Trampoline: ;以下是Target函数的继续部分 …… 拦截后: Target _ Function: jmp Detour_Function Trampoline: ;以下是Target函数的继续部分 …… Trampoline_Function: ; Trampoline函数入口, 开头的5个字节与Target函数相同 push ebp mov ebp, esp push eax push ebx ;跳回去继续执行Target函数 jmp Target_Function+5 ---- 3. 为一个已在运行的进程装入一个DLL ---- 以下是其步骤: ---- (1) 创建一个ThreadFuction,内容仅是调用LoadLibrary。 ---- (2) 用VirtualAllocEx为一个已在运行的进程分配一片虚存,并把权限更改为可读可写可执行。 ---- (3) 把ThreadFuction的二进制机器码写入这片虚存。 ---- (4) 用CreateRemoteThread在该进程上创建一个线程,传入前面分配的虚存的起始地址作为线程函数的地址,即可为一个已在运行的进程装入一个DLL。通过DllMain 即可在一个已在运行的进程中运行自己的代码。 二. Detours库函数的用法 ---- 因为Detours软件包并没有附带帮助文件,以下接口仅从剖析源代码得出。 ---- 1. PBYTE WINAPI DetourFindFunction(PCHAR pszModule, PCHAR pszFunction) ---- 功能:从一DLL中找出一函数的入口地址 ---- 参数:pszModule是DLL名,pszFunction是函数名。 ---- 返回:名为pszModule的DLL的名为pszFunction的函数的入口地址 ---- 说明:DetourFindFunctio

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧