version 2.4.1
i find mouse status address is
00D48B08
5 = mouse on fishing bobber
but i can't find fishing bobber status address.
how to find fishing bobber status??
version 2.4.1
i find mouse status address is
00D48B08
5 = mouse on fishing bobber
but i can't find fishing bobber status address.
how to find fishing bobber status??
I don't know if there's a static address for bobber status.
The only way I know to do it is by reading the TLS object list:
1) Find the your bobber. It will be a GameObj (type=5), obviously named "Fishing Bobber", and OBJECT_FIELD_CREATED_BY should equal your player GUID (else you might find some other player's bobber).
2) Read a byte at offset 244 (decimal) from the base address of the slot in the object list. 0=Normal, 1=Bobbing.
The "status" is also located in the SS_modelblock under AnimationState.
Note that the SS_modelblock does also contain the position of the bobber. Meaning that you can move the bobber and click it anywhere you want.
So if you got the position of your mouse you can just move the bobber down under your mouse and wait for the model to change animation state and then click it. It is a cool way of making a fish bot and will also avoid need for lame screen reading and color profiles etc.
Now if you are a place where the modellist updates often you might see that as a problem.
However Obj_ID is there too so you can just scan the list every time you throw you bobber to get the offset.
Thanks everybody.
i am newbie.
who talk about TLS?
TLS is thread local storge?
may i use CE or OLLYDBG view TLS index?
please help me,or Give me some information on TLS?
sorry My English is very bad.
is this info still relevent? ive tried searching for the bobber GUID (based on the mouse-over guid and player.channeled values) and none of the spots that come up had an int that equalled 5 following it, then i tried doing the created_by with the player guid and that didnt get me anywhere. using these structsso i set up a function to search for created by player GUID and then had valid x/y/z position then did a WPM to set them to player loc. the fishing line would point to my feet but the bobber didnt move.Code:enum eObjectFields { OBJECT_FIELD_GUID=0x0, OBJECT_FIELD_TYPE=0x8, OBJECT_FIELD_ENTRY=0xC, OBJECT_FIELD_SCALE_X=0x10, OBJECT_FIELD_PADDING=0x14, TOTAL_OBJECT_FIELDS=0x5 }; followed by enum eGameObjectFields { OBJECT_FIELD_CREATED_BY=0x0, GAMEOBJECT_DISPLAYID=0x8, GAMEOBJECT_FLAGS=0xC, GAMEOBJECT_ROTATION=0x10, GAMEOBJECT_STATE=0x20, GAMEOBJECT_POS_X=0x24, GAMEOBJECT_POS_Y=0x28, GAMEOBJECT_POS_Z=0x2C, GAMEOBJECT_FACING=0x30, GAMEOBJECT_DYN_FLAGS=0x34, GAMEOBJECT_FACTION=0x38, GAMEOBJECT_TYPE_ID=0x3C, GAMEOBJECT_LEVEL=0x40, GAMEOBJECT_ARTKIT=0x44, GAMEOBJECT_ANIMPROGRESS=0x48, GAMEOBJECT_PADDING=0x4C, TOTAL_GAMEOBJECT_FIELDS=0x10 };
edit: ok i found the bobber, now can anyone point me in the direction of reading whether it is bobbing, or elaborate on what was already mentioned (reading 244 (dec) from the base address of the slot(?))
Last edited by korknob; 06-12-2008 at 01:38 PM.
Dunno i haven't seen this on other threads...
as of 2.4.3
Mouse status address is = 0x00CF5750
yeah... at the base address of every object... if you followed knyox's tutorials and example code... will be...
dwCurObject
if you initialize a char and read from dwCurObject+224 you will get the status of the bobber....
the 224 is in decimal, not hex...
ReadProcessMemory( hProcess, (LPVOID)(dwCurObject + 244), (LPVOID) &status, 1, 0 );
if status = 0... its not bobbing
if status = 1...its bobbing..
alright thanks. recently switched over to TLS and got the bobbing detection working. can also get the position of the bobber but not having any luck in moving it. when i try the bobber stays put but the fishing line itself will move (such as point to my feet)
so has anyone tried moving bobbers lately, still possible?
Not hard to figure out.Code:#include "WoWFishMonger.h" CWoWFishMonger::CWoWFishMonger( HMODULE hModule ) { m_pObjectManager = new CObjectManager; Enable(); } CWoWFishMonger::~CWoWFishMonger() { Disable(); TerminateThread( m_hThreadHandle, 0 ); delete m_pObjectManager; } void CWoWFishMonger::Enable() { m_bEnabled = true; m_hThreadHandle = CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)CWoWFishMonger::Loop, NULL, NULL, NULL ); } void CWoWFishMonger::Disable() { m_bEnabled = false; } void CWoWFishMonger::Loop() { CObjectManager* pObjMgr = gWoWFisher->GetObjManager(); gWoWFisher->SetState( STATE_INIT ); srand( time( NULL ) ); while( gWoWFisher->IsEnabled() ) { switch ( gWoWFisher->GetState() ) { case STATE_INIT: gWoWFisher->SetState( STATE_CASTING ); break; case STATE_CASTING: gWoWFisher->CastSpellByName( "Fishing" ); gWoWFisher->m_dwCastTime = GetTickCount(); gWoWFisher->SetState( STATE_WAITING ); break; case STATE_WAITING: { CGameObject* pBobber = (CGameObject*)pObjMgr->GetOwnedObjectByName( "Fishing Bobber" ); if ( pBobber ) { CFishingBobber* pBobberInfo = (CFishingBobber*)pBobber->pGameObjectInfo; if ( pBobberInfo && pBobberInfo->CanUseItem() && pBobberInfo->GotBite() ) { Sleep( 1500 ); gWoWFisher->SetState( STATE_LOOTING ); } } else if ( (GetTickCount() - gWoWFisher->m_dwCastTime) / 1000 >= 3 ) // If 3 seconds have passed without a bobber.. recast gWoWFisher->SetState( STATE_CASTING ); break; } case STATE_LOOTING: { CObject* pBobber = pObjMgr->GetObjectByName( "Fishing Bobber" ); if ( pBobber ) { pBobber->UseObject(); } Sleep( gWoWFisher->GetRandomTiming() ); gWoWFisher->SetState( STATE_CASTING ); break; } } Sleep( 1 ); } ExitThread( 0 ); }
thanks for the input but i was looking for a different solution. moving the bobber lets me put it in a certain place (center of screen) and always right click the same place. ive thought about injecting for the .interact or use item function but i was under the impression that it would be easier to detect. ive currently got it set up to move the mouse around a box defined by the upper half of the screen and 1/4th the way in on each side and stop moving the mouse when cursor_guid = bobber guid but its not nearly as efficient.
that said ill probably give in and implement what you guys mentioned. is it any more detectable to code cave, and are there any specific ways to avoid detection with that method?
You'll be fine. Assuming it isn't going to turn into a huge popular hack, you don't need to worry about warden for simple code caves.
ok, i tried porting NoMorePasting.com (shynd's example for Interact) but it seems to no workie. his example was written for 2.4.2 and i assume the index/position of Interact in the vtable changed. if anyone has some insight i'd appreciate it.
yeah it doesnt look pretty, was hoping to get it working first and then clean up. i single stepped through it to verify it is allocating memory and injecting the code. GetExitCodeThread returns 0; offset is the base address of the fishing bobber.Code:void Interact(int offset) { //this is where we get our pointer as of WoW 2.4.2 // s_curMgrPointer = Memory.ReadUInt(hProcess, Memory.ReadUInt(hProcess, 0xD495B0) + 0x2218); // s_curMgr //read interact from object vtable int buf; int read; ReadProcessMemory(hProc, (LPCVOID)(offset), &buf, sizeof(int), (SIZE_T*)&read); int interact; ReadProcessMemory(hProc, (LPCVOID)(buf + (34 * 4)), &interact, sizeof(int), (SIZE_T*)&read); // uint interact = Meemory.ReadUInt(hProcess, (Memory.ReadUInt(hProcess, obj) + (34 * 4))); //allocate memory int CodeCave = (int)VirtualAllocEx(hProc, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE); // uint CodeCave = Memory.AllocateMemory(hProcess, 0x1000); unsigned char bInject [] = { 0x8B, 0x15, 0xEF, 0xBE, 0xAD, 0xDE, 0x64, 0xA1, 0x2C, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x83, 0xC0, 0x10, 0x89, 0x10, 0x8B, 0x0D, 0xEF, 0xBE, 0xAD, 0xDE, 0xE8, 0, 0, 0, 0, 0xC3}; //inject memory // Memory.WriteMemory(hProcess, CodeCave, bInject); WriteProcessMemory(hProc, (LPVOID)(CodeCave), (LPCVOID)&bInject, 31, (SIZE_T*)&read); //patch relatives // Memory.WriteMemory(hProcess, (CodeCave + 2), s_curMgrPointer); WriteProcessMemory(hProc, (LPVOID)(CodeCave+ 2), (LPCVOID)&s_curMgr, 4, (SIZE_T*)&read); // Memory.WriteMemory(hProcess, (CodeCave + 21), (CodeCave + 0x100)); buf = CodeCave + 0x100; WriteProcessMemory(hProc, (LPVOID)(CodeCave + 21), (LPCVOID)&buf, 4, (SIZE_T*)&read); // Memory.WriteMemory(hProcess, (CodeCave + 26), (interact - (CodeCave + 30))); buf = interact - (CodeCave + 30); WriteProcessMemory(hProc, (LPVOID)(CodeCave + 26), (LPCVOID)&buf, 4, (SIZE_T*)&read); //write object with which we wish to interact to memory WriteProcessMemory(hProc, (LPVOID)(CodeCave + 0x100), (LPCVOID)&offset, 4, (SIZE_T*)&read); // Memory.WriteMemory(hProcess, (CodeCave + 0x100), obj); //Execute injected code // IntPtr hThread = Memory.CreateRemoteThread(hProcess, CodeCave, 0); HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)CodeCave, 0, 0, NULL); //wait for code to execute WaitForSingleObject(hThread, INFINITE); int buf2; GetExitCodeThread(hThread, (LPDWORD)&buf2); CloseHandle(hThread); // Memory.WaitForSingleObject(hThread); //uint ec = Memory.GetExitCodeThread(hThread); //clean up // Memory.CloseHandle(hThread); // Memory.VirtualFreeEx(hProcess, CodeCave, 0x1000, Memory.MEM_DECOMMIT); VirtualFreeEx(hProc, (LPVOID)CodeCave, 0x1000, MEM_DECOMMIT); }
Holy christ that code is ugly!
yeah... we established that. i copied and pasted shynd's code then commented it out and wrote a c++ version in its place, to be cleaned up after its functional.
now, assuming his example was correct, and i single stepped the function and verified it did everything it was supposed to, my question is, did the position of Interact change in the vtable in 2.4.3?
this is why i was hesitant to try this method because it was more prone to break between patches. if it makes you feel better i can paste a version with all of shynd's commented code removed but i left it there as a reference.
Code:void Interact(int offset) { int buf; // buffer for addition int read; // required for RPM ReadProcessMemory(hProc, (LPCVOID)(offset), &buf, sizeof(int), (SIZE_T*)&read); int interact; ReadProcessMemory(hProc, (LPCVOID)(buf + (34 * 4)), &interact, sizeof(int), (SIZE_T*)&read); // read interact from vtable int CodeCave = (int)VirtualAllocEx(hProc, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE); // allocate memory for code cave unsigned char bInject [] = { 0x8B, 0x15, 0xEF, 0xBE, 0xAD, 0xDE, 0x64, 0xA1, 0x2C, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x83, 0xC0, 0x10, 0x89, 0x10, 0x8B, 0x0D, 0xEF, 0xBE, 0xAD, 0xDE, 0xE8, 0, 0, 0, 0, 0xC3}; WriteProcessMemory(hProc, (LPVOID)(CodeCave), (LPCVOID)&bInject, 31, (SIZE_T*)&read); // inject code into codecave //patch relatives WriteProcessMemory(hProc, (LPVOID)(CodeCave+ 2), (LPCVOID)&s_curMgr, 4, (SIZE_T*)&read); buf = CodeCave + 0x100; WriteProcessMemory(hProc, (LPVOID)(CodeCave + 21), (LPCVOID)&buf, 4, (SIZE_T*)&read); buf = interact - (CodeCave + 30); WriteProcessMemory(hProc, (LPVOID)(CodeCave + 26), (LPCVOID)&buf, 4, (SIZE_T*)&read); WriteProcessMemory(hProc, (LPVOID)(CodeCave + 0x100), (LPCVOID)&offset, 4, (SIZE_T*)&read); //offset is base address of obj HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)CodeCave, 0, 0, NULL); //start thread to execute code WaitForSingleObject(hThread, INFINITE); //wait for code to execute CloseHandle(hThread); // close thread VirtualFreeEx(hProc, (LPVOID)CodeCave, 0x1000, MEM_DECOMMIT); // free memory }