[Announce] Model Edits 4.0.3a menu

User Tag List

Page 1 of 14 12345 ... LastLast
Results 1 to 15 of 204
  1. #1
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Announce] Model Edits 4.0.3a

    Hey there!

    Ive seen some posts here that in 4.0.3a its now not longer possible to just add the MPQ to the data folder as WoW wont load it. After testing it ive seen that this is true. I have no clue if there is already something here to avoid that error, but ive done some research and made a little exe that injects the MPQs into WoW (forces WoW to load the MPQ). Needs still some tweaks to ensure that you can close WoW without errors. But just wanted to inform you and ask if there is already something else done solving the problem.

    Heres a screenshot (replaced all the WMOs with that cave just to test):
    http://imagr.eu/up/4d1691f54f3a23_Wo...610_014834.jpg

    Greetings
    Cromon

    [Announce] Model Edits 4.0.3a
  2. #2
    skittay's Avatar Private
    Reputation
    1
    Join Date
    Dec 2010
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    An injector? o_o

    I haven't seen anything similar, let alone any way to race change in 4.0.3a at all, anything is welcome!

  3. #3
    Garneth's Avatar Contributor
    Reputation
    97
    Join Date
    Jul 2010
    Posts
    424
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So basically, this program will, assuming I put the .mpq file into the data folder in my WOW Folder, force wow to accept the model change?

  4. #4
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, it makes possible again what worked with 3.3.5 (or 4.0.1). So any changes work again.

  5. #5
    skittay's Avatar Private
    Reputation
    1
    Join Date
    Dec 2010
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    well share it up, if injectors are safe

  6. #6
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    They of course aren't safe if you play on retail. They may be safe, but i don't know which sections warden all scans for changes but if i would be blizzard id let the MPQ-list be checked by warden. Ill post it as soon as i fixed this nasty bug that occurs since this morning...

  7. #7
    T4PO's Avatar Member
    Reputation
    10
    Join Date
    May 2009
    Posts
    18
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    finally, some1 is trying to redeem the 4.0.3a model editing

  8. #8
    MadameGrip's Avatar Contributor

    Reputation
    150
    Join Date
    Aug 2010
    Posts
    528
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This... Cromon I want to donate a few bucks for your effort and contribution into the model editing section Is that possible?

  9. #9
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, removed the bug. Now it just in rare cases crashes when you inject many MPQs (ive injected 202 MPQs and there sometimes it can crash, dont know yet what the reason is).

    Thats the code for the DLL (call it Mopaq.dll):
    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    #include <Windows.h>
    
    struct SFileArchive
    {
    	int m_type;
    	int m_handle;
    };
    
    typedef bool (__stdcall *tSFileOpenArchive)(const char* file, int zero, int flags, SFileArchive** ppNode);
    typedef int (__stdcall *tSFileSystem__AddMPQ)(SFileArchive* node, const char* prefix, int zero, int unk, SFileArchive** dest);
    typedef int (__stdcall *tArray__Unk)(int unkNum);
    typedef int (__stdcall *tArray__Resize)(int unkNum);
    
    #define GetAddr(T, A) ((T)((DWORD)GetModuleHandle(NULL) + A))
    
    extern "C"
    __declspec(dllexport) unsigned long InjectFunction(LPVOID)
    {
    	tSFileOpenArchive SFileOpenArchive = GetAddr(tSFileOpenArchive, 0x303E20);
    	tSFileSystem__AddMPQ SFileSystem__AddMPQ = GetAddr(tSFileSystem__AddMPQ, 0x303FA0);
    	tArray__Unk Array__Unk = GetAddr(tArray__Unk, 0x2BA7D0);
    	tArray__Resize Array__Resize = GetAddr(tArray__Resize, 0x32D0);
    
    	LPDWORD lpNumArchives = GetAddr(LPDWORD, 0x831A44);
    	SFileArchive*** lpArchives = GetAddr(SFileArchive***, 0x831A48);
    	LPDWORD lpCapacity = GetAddr(LPDWORD, 0x831A40);
    	LPDWORD lpGain = GetAddr(LPDWORD, 0x831A4C);
    
    	std::ifstream input("MpqFiles.txt");
    	if(!input.is_open())
    	{
    		std::cout << "Could not locate or open \"MpqFiles.txt\" in wow directory!" << std::endl;
    		ExitThread(0);
    	}
    
    	std::string curFile;
    	while(std::getline(input, curFile))
    	{
    		std::ifstream tst(curFile);
    		std::cout << "Loading file '" << curFile << "'..." << std::endl;
    		if(!tst.is_open())
    		{
    			std::cout << "file does not exist!" << std::endl;
    			continue;
    		}
    
    		tst.close();
    
    		SFileArchive* pNode = NULL;
    		if(!SFileOpenArchive(curFile.c_str(), 0, 0, &pNode))
    		{
    			std::cout << "SFileOpenArchive returned false!" << std::endl;
    			continue;
    		}
    
    		++(*lpNumArchives);
    		if(*lpNumArchives > *lpCapacity)
    		{
    			DWORD gain = *lpGain;
    			if(!gain)
    			{
    				DWORD v4 = *lpNumArchives;
    				DWORD pThis = GetAddr(DWORD, 0x831A40);
    				__asm
    				{
    					mov eax, v4
    					push eax
    					lea ecx, pThis
    					lea eax, Array__Unk
    					call far eax
    					mov gain, eax
    				}
    			}
    
    			DWORD v4 = *lpNumArchives;
    			if(v4 % gain)
    				v4 = *lpNumArchives + gain - *lpNumArchives % gain;
    			
    			DWORD pThis = GetAddr(DWORD, 0x831A40);
    			__asm
    			{
    				mov eax, v4
    				push eax
    				mov ecx, pThis
    				mov eax, Array__Resize
    				call far eax
    			}
    		}
    
    		SFileSystem__AddMPQ(pNode, NULL, 64 + *lpNumArchives, 0, *lpArchives + *lpNumArchives);
    	}
    
    	ExitThread(0);
    }
    And for the Exe that loads the dll:
    Code:
    #include <iostream>
    #include <cassert>
    #include <windows.h>
    
    int main()
    {
    	HWND hWindow = FindWindow("GxWindowClass", "World of Warcraft");
    	assert(hWindow != NULL);
    
    	DWORD dwProcess = 0;
    	assert(GetWindowThreadProcessId(hWindow, &dwProcess) != FALSE);
    
    	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcess);
    	assert(hProcess != NULL);
    
    	CHAR szProc[MAX_PATH];
    	GetCurrentDirectory(MAX_PATH, szProc);
    
    	LPVOID dllAddr = VirtualAllocEx(hProcess, NULL, strlen(szProc) + 1, MEM_COMMIT, PAGE_READWRITE);
    	assert(dllAddr != NULL);
    
    	DWORD dwRet = WriteProcessMemory(hProcess, dllAddr, szProc, strlen(szProc) + 1, NULL);
    	assert(dwRet == TRUE);
    
    	HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)SetDllDirectory, dllAddr, 0, NULL);
    	assert(hThread != NULL);
    
    	dwRet = WaitForSingleObject(hThread, INFINITE);
    	assert(dwRet == WAIT_OBJECT_0);
    
    	VirtualFreeEx(hProcess, dllAddr, strlen(szProc) + 1, MEM_COMMIT);
    
    	HMODULE hDll = LoadLibrary("Mopaq.dll");
    	FARPROC fp = GetProcAddress(hDll, "InjectFunction");
    	assert(fp != NULL && (DWORD)hDll < (DWORD)fp);
    
    	DWORD dwOffset = (DWORD)fp - (DWORD)hDll;
    
    	CHAR szDllName[] = "Mopaq.dll";
    	dllAddr = VirtualAllocEx(hProcess, NULL, strlen(szDllName) + 1, MEM_COMMIT, PAGE_READWRITE);
    	assert(dllAddr != NULL);
    
    	dwRet = WriteProcessMemory(hProcess, dllAddr, szDllName, strlen(szDllName) + 1, NULL);
    	assert(dwRet == TRUE);
    
    	hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, dllAddr, 0, NULL);
    	assert(hThread != NULL);
    
    	dwRet = WaitForSingleObject(hThread, INFINITE);
    	assert(dwRet == WAIT_OBJECT_0);
    
    	HMODULE hRemote = NULL;
    	dwRet = GetExitCodeThread(hThread, (LPDWORD)&hRemote);
    	assert(dwRet == TRUE);
    	assert(hRemote != NULL);
    	
    	VirtualFreeEx(hProcess, dllAddr, strlen(szDllName) + 1, MEM_COMMIT);
    
    	LPTHREAD_START_ROUTINE initProc = (LPTHREAD_START_ROUTINE)((DWORD)hRemote + dwOffset);
    	hThread = CreateRemoteThread(hProcess, NULL, 0, initProc, NULL, 0, NULL);
    	assert(hThread != NULL);
    
    	dwRet = WaitForSingleObject(hThread, INFINITE);
    	assert(dwRet == WAIT_OBJECT_0);
    
    	hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, (LPVOID)hRemote, 0, NULL);
    	WaitForSingleObject(hThread, INFINITE);
    
    	return 0;
    }
    How to do:
    - Compile DLL-code to Mopaq.dll (dunno if it works for other compilers then M$, didnt look for portability)
    - Compile Exe-code to random exe file (dunno if it works for other compilers then M$, didnt look for portability)
    - Place DLL and exe into the same folder (no matter where)
    - In the wow-directory (NOT data) create a file named MpqFiles.txt
    - Write the path to each MPQ on one line. Paths can be relative to the WoW-Directory (e.g. Data\myPatch.MPQ) or absolute (e.g. C:\Patches\myPatch.mpq)
    - Start WoW
    - At login screen run exe. If something goes wrong a large box pops up and after pressing abort you see an error message in the console.
    - MPQs are injected now and loaded

    Hints:
    - Start the exe using CMD to prevent the window from being closed to see the error messages.
    ...

    Preview:
    - Loading MPQs before WoW loads the DBC to also make changes on DBC possible. Or delayed reloading of DBCs at loading screen (not prefered )
    - Compiled binaries

  10. #10
    Jimbob99's Avatar Private
    Reputation
    2
    Join Date
    Dec 2010
    Posts
    11
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Compiled with VS10 no problems after setting multi-byte.

    Works with live at the moment just fine, as well - but I'm on a Trial account so...

    Thank you.

  11. #11
    tikigenius's Avatar Member
    Reputation
    1
    Join Date
    Sep 2007
    Posts
    10
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Outstanding work. I haven't attempted to use it yet, but the theory behind it looks pretty sound. Bravo for providing the source as well. I wonder if the old scan.dll hack would work for this to protect it from Warden.

  12. #12
    Xel's Avatar ★ Elder ★
    Authenticator enabled
    Reputation
    1179
    Join Date
    Jul 2008
    Posts
    2,906
    Thanks G/R
    94/51
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for this release, couldn't live without
    Last edited by Xel; 01-16-2011 at 01:06 PM.

  13. #13
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Extended the tool to load the MPQs before any file is taken from the MPQ, this allows changes in login screen/DBC and all the other stuff that is loaded during startup. Code is a bit ugly at the moment, will clean it up a bit before posting it here, but thats a brief description how its done:
    1. Tool starts WoW in suspended mode (main thread is halted at first instruction)
    2. Tool writes a hardware breakpoint in the debug registers of the main thread to fire when wows main thread reaches the clients SFileSystem::LoadAllArchives function.
    3. Tool loads a DLL into wows memory and calls a function inside the DLL.
    4. Called functions installs a vectored exception handler inside WoW and creates a system wide event (SyncEvent), which will be fired later
    5. Tool lets wow main thread run again (ResumeThread)
    6. Tool acquires handle to the system wide event (SyncEvent) and waits until its fired and before that creates another system wide event (FinishEvent)
    7. When the exception handler in the DLL gets called and the code is EXCEPTION_SINGLE_STEP at SFileSystem::LoadAllArchives it gets active
    8. Exception handler removes the breakpoint, removes itself from the exception chain and signals the SyncEvent and waits until FinishEvent is fired
    9. As the main thread in wow is now paused until FinishEvent is fired the tool now loads the MPQs as usual and fires the FinishEvent
    10. As FinishEvent was fired the ExceptionHandler now continues and tells wow that the exception is handled and it should continue executing
    11. Tool removes both DLLs from WoWs memory.

    /Edit:
    Example image with changed buttons (taken from WOTLK):

  14. #14
    Garneth's Avatar Contributor
    Reputation
    97
    Join Date
    Jul 2010
    Posts
    424
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can you please just upload an EXE or something....im horrible with this code stuff...can any1 help?

  15. #15
    Cromon's Avatar Legendary


    Reputation
    840
    Join Date
    Mar 2008
    Posts
    714
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, heres the code for the new version. You need to make 2 DLLs.

    First DLL (VectoredHandler.dll)
    Code:
    #include <Windows.h>
    #include <iostream>
    
    static PVOID ExceptionHandler = NULL;
    static HANDLE CommEvent = NULL;
    static HANDLE FinishEvent = NULL;
    
    LONG WINAPI VectoredExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo)
    {
    	if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
    	{
    		if(ExceptionInfo->ExceptionRecord->ExceptionAddress == (LPVOID)((DWORD)GetModuleHandle(NULL) + 0x6176))
    		{
    			ExceptionInfo->ContextRecord->EFlags &= ~0x100;
    			ExceptionInfo->ContextRecord->Dr7 &= ~1;
    
    			RemoveVectoredExceptionHandler(ExceptionHandler);
    			SetEvent(CommEvent);
    			WaitForSingleObject(FinishEvent, INFINITE);
    
    			CloseHandle(CommEvent);
    			CloseHandle(FinishEvent);
    
    			return EXCEPTION_CONTINUE_EXECUTION;
    		}
    	}
    
    	return EXCEPTION_CONTINUE_SEARCH;
    }
    
    extern "C"
    __declspec(dllexport) void AddHandler(LPVOID)
    {
    	char name[255];
    	sprintf(name, "Global\\_CommMutex_%u", GetCurrentProcessId());
    	CommEvent = CreateEvent(NULL, FALSE, FALSE, name);
    	sprintf(name, "Global\\_FinishEvent_%u", GetCurrentProcessId());
    	FinishEvent = CreateEvent(NULL, FALSE, FALSE, name);
    
    	ExceptionHandler = AddVectoredExceptionHandler(1, &VectoredExceptionHandler);
    	ExitThread(0);
    }
    Second DLL (same as old one, called Mopaq.dll):
    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    #include <Windows.h>
    
    struct SFileArchive
    {
    	int m_type;
    	int m_handle;
    };
    
    typedef bool (__stdcall *tSFileOpenArchive)(const char* file, int zero, int flags, SFileArchive** ppNode);
    typedef int (__stdcall *tSFileSystem__AddMPQ)(SFileArchive* node, const char* prefix, int zero, int unk, SFileArchive** dest);
    typedef int (__stdcall *tArray__Unk)(int unkNum);
    typedef int (__stdcall *tArray__Resize)(int unkNum);
    
    #define GetAddr(T, A) ((T)((DWORD)GetModuleHandle(NULL) + A))
    
    extern "C"
    __declspec(dllexport) unsigned long InjectFunction(LPVOID)
    {
    	tSFileOpenArchive SFileOpenArchive = GetAddr(tSFileOpenArchive, 0x303E20);
    	tSFileSystem__AddMPQ SFileSystem__AddMPQ = GetAddr(tSFileSystem__AddMPQ, 0x303FA0);
    	tArray__Unk Array__Unk = GetAddr(tArray__Unk, 0x2BA7D0);
    	tArray__Resize Array__Resize = GetAddr(tArray__Resize, 0x32D0);
    
    	LPDWORD lpNumArchives = GetAddr(LPDWORD, 0x831A44);
    	SFileArchive*** lpArchives = GetAddr(SFileArchive***, 0x831A48);
    	LPDWORD lpCapacity = GetAddr(LPDWORD, 0x831A40);
    	LPDWORD lpGain = GetAddr(LPDWORD, 0x831A4C);
    
    	std::ifstream input("MpqFiles.txt");
    	if(!input.is_open())
    	{
    		std::cout << "Could not locate or open \"MpqFiles.txt\" in wow directory!" << std::endl;
    		ExitThread(0);
    	}
    
    	std::string curFile;
    	while(std::getline(input, curFile))
    	{
    		std::ifstream tst(curFile);
    		std::cout << "Loading file '" << curFile << "'..." << std::endl;
    		if(!tst.is_open())
    		{
    			std::cout << "file does not exist!" << std::endl;
    			continue;
    		}
    
    		tst.close();
    
    		SFileArchive* pNode = NULL;
    		if(!SFileOpenArchive(curFile.c_str(), 0, 0, &pNode))
    		{
    			std::cout << "SFileOpenArchive returned false!" << std::endl;
    			continue;
    		}
    
    		++(*lpNumArchives);
    
    		if(*lpNumArchives > *lpCapacity)
    		{
    			DWORD gain = *lpGain;
    			if(!gain)
    			{
    				DWORD v4 = *lpNumArchives;
    				DWORD pThis = GetAddr(DWORD, 0x831A40);
    				__asm
    				{
    					mov eax, v4
    					push eax
    					lea ecx, pThis
    					lea eax, Array__Unk
    					call far eax
    					mov gain, eax
    				}
    			}
    
    			DWORD v4 = *lpNumArchives;
    			if(v4 % gain)
    				v4 = *lpNumArchives + gain - *lpNumArchives % gain;
    			
    			DWORD pThis = GetAddr(DWORD, 0x831A40);
    			__asm
    			{
    				mov eax, v4
    				push eax
    				mov ecx, pThis
    				mov eax, Array__Resize
    				call far eax
    			}
    		}
    
    		SFileSystem__AddMPQ(pNode, NULL, 64 + *lpNumArchives, 0, *lpArchives + *lpNumArchives);
    	}
    
    	ExitThread(0);
    }
    Exe code:
    Code:
    #include <iostream>
    #include <cassert>
    #include <string>
    #include <windows.h>
    #include <winternl.h>
    
    HANDLE hProcess;
    
    void StartupInject(HANDLE);
    void AdjustDllDirectory(HANDLE);
    HMODULE LoadDll(HANDLE, LPSTR);
    template<typename T>
    void CallFunc(HANDLE, T func, LPVOID param); 
    DWORD GetFuncOffset(LPSTR szDll, LPSTR szFunc);
    
    int main(int argc, char* argv[])
    {
    	PROCESS_INFORMATION pi;
    	if(argc >= 2)
    	{
    		std::string wowPath;
    		std::string curDir;
    		if(!stricmp(argv[1], "-nodelay"))
    		{
    			if(argc > 2)
    			{
    				curDir = argv[2];
    				wowPath = std::string(argv[2]) + "\\WoW.exe";
    			}
    			else
    			{
    				CHAR dir[MAX_PATH];
    				GetCurrentDirectory(MAX_PATH, dir);
    				curDir = dir;
    				wowPath = "WoW.exe";
    			}
    
    			STARTUPINFO startInfo;
    			memset(&startInfo, 0, sizeof(startInfo));
    			startInfo.cb = sizeof(startInfo);
    			memset(&pi, 0, sizeof(pi));
    			if(!CreateProcess(wowPath.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE, NULL, curDir.c_str(), &startInfo, &pi))
    			{
    				if(GetLastError() == ERROR_NOACCESS || GetLastError() == ERROR_DIRECTORY)
    				{
    					std::cout << "File " << wowPath << " does not exist!" << std::endl;
    					return 0;
    				}
    				std::cout << "Failed to launch WoW in suspended mode! (Error: " << GetLastError() << ")" << std::endl;
    				return 0;
    			}
    
    			hProcess = pi.hProcess;
    			StartupInject(pi.hThread);
    			return 0;
    		}
    		else
    		{
    			bool commandLineRecognized = false;
    			assert(commandLineRecognized == true);
    		}
    	}
    
    
    	HWND hWindow = FindWindow("GxWindowClass", "World of Warcraft");
    	assert(hWindow != NULL);
    
    	DWORD dwProcess = 0;
    	assert(GetWindowThreadProcessId(hWindow, &dwProcess) != FALSE);
    
    	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcess);
    	assert(hProcess != NULL);
    
    	AdjustDllDirectory(hProcess);
    
    	HMODULE hDll = LoadLibrary("Mopaq.dll");
    	DWORD dwOffset = GetFuncOffset("Mopaq.dll", "InjectFunction");
    
    	HMODULE hRemote = LoadDll(hProcess, "Mopaq.dll");
    
    	CallFunc(hProcess, (DWORD)hRemote + dwOffset, NULL);
    	CallFunc(hProcess, FreeLibrary, NULL);
    
    	return 0;
    }
    
    typedef NTSTATUS (__stdcall *tNtQueryInformationProcess)(HANDLE hProcess, PROCESSINFOCLASS info, PVOID infoBuffer, ULONG infoLen, PULONG retLen);
    
    
    void StartupInject(HANDLE hThread)
    {
    	HMODULE hNtDll = LoadLibrary("ntdll.dll");
    	tNtQueryInformationProcess NtQueryInformationProcess = (tNtQueryInformationProcess)GetProcAddress(hNtDll, "NtQueryInformationProcess");
    
    	PROCESS_BASIC_INFORMATION pbi;
    	NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
    	PEB peb;
    	ReadProcessMemory(hProcess, (LPCVOID)pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
    	DWORD dwBase = (DWORD)peb.Reserved3[1];
    
    	CONTEXT ctx;
    	ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
    	assert(GetThreadContext(hThread, &ctx) != FALSE);
    
    	int index = 0;
    
    	DWORD dwFunction = dwBase + 0x6176;
    	ctx.Dr0 = dwFunction;
    
    	ctx.Dr7 |= (3 << 24);
    	ctx.Dr7 |= 1;
    
    	assert(SetThreadContext(hThread, &ctx));
    
    	AdjustDllDirectory(hProcess);
    	
    	DWORD offset = GetFuncOffset("VectoredHandler.dll", "AddHandler");
    
    	HMODULE hRemote = LoadDll(hProcess, "VectoredHandler.dll");
    
    	char name[255];
    	sprintf(name, "Global\\_FinishEvent_%u", GetProcessId(hProcess));
    
    	HANDLE hFinish = CreateEvent(NULL, FALSE, FALSE, name);
    
    	CallFunc(hProcess, (DWORD)hRemote + offset, NULL);
    
    	sprintf(name, "Global\\_CommMutex_%u", GetProcessId(hProcess));
    	HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, name);
    
    	ResumeThread(hThread);
    
    	WaitForSingleObject(hEvent, INFINITE);
    
    	offset = GetFuncOffset("Mopaq.dll", "InjectFunction");
    	HMODULE hMpq = LoadDll(hProcess, "Mopaq.dll");
    
    	CallFunc(hProcess, (DWORD)hMpq + offset, NULL);
    	CallFunc(hProcess, FreeLibrary, hMpq);
    	SetEvent(hFinish);
    
    	CloseHandle(hFinish);
    	CloseHandle(hEvent);
    
    	// Wait a second to let the vectored exception handler return. Hacky, but will work
    	Sleep(1000);
    
    	CallFunc(hProcess, FreeLibrary, hRemote);
    	CloseHandle(hProcess);
    	CloseHandle(hThread);
    }
    
    void AdjustDllDirectory(HANDLE hProc)
    {
    	CHAR szProc[MAX_PATH];
    	GetCurrentDirectory(MAX_PATH, szProc);
    
    	LPVOID dllAddr = VirtualAllocEx(hProc, NULL, strlen(szProc) + 1, MEM_COMMIT, PAGE_READWRITE);
    	assert(dllAddr != NULL);
    
    	DWORD dwRet = WriteProcessMemory(hProc, dllAddr, szProc, strlen(szProc) + 1, NULL);
    	assert(dwRet == TRUE);
    
    	HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)SetDllDirectory, dllAddr, 0, NULL);
    	assert(hThread != NULL);
    
    	dwRet = WaitForSingleObject(hThread, INFINITE);
    	assert(dwRet == WAIT_OBJECT_0);
    
    	VirtualFreeEx(hProc, dllAddr, strlen(szProc) + 1, MEM_COMMIT);
    }
    
    HMODULE LoadDll(HANDLE hProc, LPSTR szDll)
    {
    	LPVOID dllAddr = VirtualAllocEx(hProc, NULL, strlen(szDll) + 1, MEM_COMMIT, PAGE_READWRITE);
    	assert(dllAddr != NULL);
    
    	DWORD dwRet = WriteProcessMemory(hProc, dllAddr, szDll, strlen(szDll) + 1, NULL);
    	assert(dwRet == TRUE);
    
    	HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, dllAddr, 0, NULL);
    	assert(hThread != NULL);
    
    	dwRet = WaitForSingleObject(hThread, INFINITE);
    	assert(dwRet == WAIT_OBJECT_0);
    
    	HMODULE hRemote = NULL;
    	dwRet = GetExitCodeThread(hThread, (LPDWORD)&hRemote);
    	assert(dwRet == TRUE);
    	assert(hRemote != NULL);
    	
    	VirtualFreeEx(hProc, dllAddr, strlen(szDll) + 1, MEM_COMMIT);
    
    	return hRemote;
    }
    
    template<typename T>
    void CallFunc(HANDLE hProc, T func, LPVOID param)
    {
    	LPTHREAD_START_ROUTINE initProc = (LPTHREAD_START_ROUTINE)func;
    	HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, initProc, param, 0, NULL);
    	assert(hThread != NULL);
    
    	DWORD dwRet = WaitForSingleObject(hThread, INFINITE);
    	assert(dwRet == WAIT_OBJECT_0);
    }
    
    DWORD GetFuncOffset(LPSTR szDll, LPSTR szFunc)
    {
    	HMODULE hMod = LoadLibrary(szDll);
    	assert(hMod != NULL);
    	FARPROC proc = GetProcAddress(hMod, szFunc);
    	assert(proc != NULL);
    
    	LONG offset = (LONG)proc - (LONG)hMod;
    	assert(offset >= 0);
    
    	FreeLibrary(hMod);
    
    	return offset;
    }
    Starting it is now different:
    - Use command line option -nodelay to actively start wow and inject MPQs before any file is loaded. You need to put where Wow.exe is located in quotation marks (e.g.: Injector.exe -nodelay "C:\WoW\Client\World of Warcraft\")
    - Without command line it behaves like the old version.
    - With an infalid command line you get an error.

    And another picture
    Last edited by Cromon; 12-27-2010 at 03:45 PM.

Page 1 of 14 12345 ... LastLast

Similar Threads

  1. Model Editing Fun!
    By Matt in forum World of Warcraft Model Editing
    Replies: 100
    Last Post: 01-22-2007, 05:41 PM
  2. 45 minutes of model editing and path exploiting
    By Matt in forum World of Warcraft General
    Replies: 2
    Last Post: 09-17-2006, 09:51 PM
  3. Possible Model Editting (1.11) ?!
    By nobodyzero in forum World of Warcraft Exploits
    Replies: 9
    Last Post: 07-14-2006, 11:47 AM
  4. a model edit
    By Relz in forum World of Warcraft General
    Replies: 12
    Last Post: 07-12-2006, 09:38 PM
  5. questions about model editing
    By Avianar47 in forum World of Warcraft General
    Replies: 2
    Last Post: 07-08-2006, 09:41 PM
All times are GMT -5. The time now is 03:45 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search