d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Im Bored
Prev123
Closed New Topic New Poll
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 24 2013 02:49am
after 6+ hours of googling why codeblocks and mingw gcc is a piece of shit i finally fixed my problem with my dll not injecting proporly. apparently since codeblocks automatically compiles the dll as c++ but my game was in C the game would not call dllmain() because it wasnt exported as a C function by way of defining it as

Code
extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)


that was a fucking journey to fix that. at least now i wont ever run into that problem again... ever...

some screenies... when i wake up i will prolly start a new post with clean code and large descriptive paragraphs or something.



Member
Posts: 24,396
Joined: Oct 21 2007
Gold: 0.38
Mar 25 2013 11:26pm
If really bored, you should learn Haskell. ^_^


Everything you'd ever need:

http://shuklan.com/haskell/lec01.html#/
http://learnyouahaskell.com/chapters
http://book.realworldhaskell.org/read/

This post was edited by DeadlySanity on Mar 25 2013 11:27pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 26 2013 01:21am
Quote (DeadlySanity @ Mar 26 2013 01:26am)


da fuq i just read
Member
Posts: 24,396
Joined: Oct 21 2007
Gold: 0.38
Mar 27 2013 12:48pm
Quote (AbDuCt @ Mar 26 2013 02:21am)
da fuq i just read


An ever growing purely functional language. It can actually give you a much broader perspective of coding that's quite helpful/interesting.

The first link is a current online course through U of Virginia, with links at the top to the other lectures (you can essentially skip the first one, doesn't teach anything just talks about Haskell). They add new lectures every Tuesday.



Just figured I'd pass it along since I'm loving it right now.
^_^

This post was edited by DeadlySanity on Mar 27 2013 12:48pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 27 2013 02:17pm
Quote (DeadlySanity @ Mar 27 2013 02:48pm)
An ever growing purely functional language. It can actually give you a much broader perspective of coding that's quite helpful/interesting.

The first link is a current online course through U of Virginia, with links at the top to the other lectures (you can essentially skip the first one, doesn't teach anything just talks about Haskell). They add new lectures every Tuesday.



Just figured I'd pass it along since I'm loving it right now.
^_^


ill pass.

as for this project/blog, i will continue on after the weekend making a youtube video about CE / OllyDbg. I will have the source code for the game side by side Olly so you can sort of visualize what the assembly is doing BUT in a real instance you cannot do this.
Member
Posts: 11,637
Joined: Feb 2 2004
Gold: 434.84
Mar 27 2013 05:29pm
Quote (DeadlySanity @ Mar 26 2013 12:26am)


Yay, reading material.
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 29 2013 02:52am
meh trying to just play around with this stuff a bit but i cant seem to get the memory addresses to work for me lol

i reversed perfect world's character structure and tried to recreate it as best i could. i even found the base address which never changes and managed to find the offsets so that i can allways 100% get back into the character structure even if the game is restarted and pointers change.

how it works is

Code
BASE ADDRESS(ptr)->ANOTHER ADDRESS(ptr)+34->DATA STRUCTURE


the base address never changes and as long as you add an offset of 34 to the second pointer you will always be placed at the beginning of the structure. knowing this i recreated the structure as best i could and then tried to point the address at it hopefully allowing me to simple do

Code
Stats->p_player->Current_HP;


and since p_player would be pointing to the begining of the structure all other memory address should line up allowing me to do this in theory. alas i cant calculate the address properly. it always overshoots the address i need and segfaults the game

Code
#include "main.h"

//base address: 00BBC9CC

typedef struct
{
   BYTE Unknown01[0x488]; //Unknown stuff (skip it all and align it with the stuff we do know)
   DWORD Id;
   DWORD Level;
   DWORD Cultivation;  //create defines for cultivations 0-22
   DWORD Current_HP;
   DWORD Current_MP;
   DWORD Exp;
   DWORD Spirit;
   DWORD Attribute_Points;
   DWORD Current_Chi;
   DWORD Attack_Level;
   DWORD Defence_Level;
   float Critical_Rate;
   float Rage_Damage;
   DWORD Stealth_Level;
   DWORD Stealth_Detection_Level;
   DWORD Slaying_Level;
   DWORD Warding_level;
   DWORD Vitality_Points;
   DWORD Magic_Points;
   DWORD Strength_Points;
   DWORD Dextarity_Points;
   DWORD Max_HP;
   DWORD Max_MP;
   DWORD HP_Regen;
   DWORD MP_Regen;
   float Walk_Speed;
   float Run_Speed;
   float Swim_Speed;
   float Fly_Speed;
   DWORD Accuracy;
   DWORD Min_Attack_Damage;
   DWORD Max_Attack_Damage;
   float Attack_Rate; // 20/value
   float Range;
   DWORD Min_Metal_Damage;
   DWORD Max_Metal_Damage;
   DWORD Min_Wood_Damage;
   DWORD Max_Wood_Damage;
   DWORD Min_Water_Damage;
   DWORD Max_Water_Damage;
   DWORD Min_Fire_Damage;
   DWORD Max_Fire_Damage;
   DWORD Min_Earth_Damage;
   DWORD Max_Earth_Damage;
   DWORD Min_Magic_Damage;
   DWORD Max_Magic_Damage;
   DWORD Metal_Defence;
   DWORD Wood_Defence;
   DWORD Water_Defence;
   DWORD Fire_Defence;
   DWORD Earth_Defence;
   DWORD Physical_Defence;
   DWORD Evasion;
   DWORD Max_Chi;
   DWORD Coins;
   DWORD Max_Coins;
}PLAYER;

typedef struct
{
   BYTE Unknown[0x34]; //move ahead 0x34 bytes (52 bytes)
   PLAYER *p_player;  //this should align the address to BASEPTR->ADDRPTR+34->actual address
}VARBASE;


DLL_EXPORT void SomeFunction(const LPCSTR sometext)
{
   MessageBox(0, sometext, "DLL is inside process", 0);
}

DWORD WINAPI function()
{
   VARBASE *Stats = (VARBASE*)0x00BBC9CC;

   char lol[1000];

   sprintf(lol, "stats pointer: %p  |  player pointer: %p  |  player pointer + 34: %ld", (void*)Stats, (void*)Stats->p_player, (Stats->p_player->Level));
   SomeFunction(lol);

   return NULL;
}

DLL_EXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
   switch (fdwReason)
   {
       case DLL_PROCESS_ATTACH:
           DisableThreadLibraryCalls(hinstDLL);
           SomeFunction("Creating thread");
           CreateThread(0, 0, (LPTHREAD_START_ROUTINE)function, 0, 0, 0);
           break;
   }
   return TRUE;
}


for some reason no matter what i try the second pointers address is never correct. its always 2,500 - 75,000 bytes ahead of what it should be. and i know for a fact that the offset is 0x34 because i can pull up all the character details through cheatengine using baseptr->prt+34->address+offset (offset being which data you want to pull from the structure)

so idk im going to have to look into it in the morning, but its really pissing me off lol. there is no reason why this should work. for some reason the second pointer after i try moving ahead 0x34 bytes points to 0x00000301 rather then 0x0A**CDF4 like it always does in cheat engine. (the base address always points to somewhere around 0x0A**CDC0)

This post was edited by AbDuCt on Mar 29 2013 02:55am
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 29 2013 02:59pm
fixed my problem. it turns out i had to dereference the base address pointer and then pass that address to my VARBASE structure which would then add 0x34 and point to my character structure in PWI

Code
DWORD WINAPI function()
{
   FILE *fp;
   fp = fopen("testaddr.txt", "a+");
   DWORD *ptr = (DWORD*)0x00BBC9CC;
   VARBASE *Stats = (VARBASE*)*ptr;
   fprintf(fp, "Current level: %ld\n", Stats->p_player->Level);
   fprintf(fp, "Current hp: %ld/%ld\n", Stats->p_player->Current_HP, Stats->p_player->Max_HP);
   fprintf(fp, "Current Mana: %ld/%ld", Stats->p_player->Current_MP, Stats->p_player->Max_MP);
   fclose(fp);
   return NULL;
}


output
Code
Current level: 101
Current hp: 7111/7111
Current Mana: 2343/2343
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 29 2013 10:26pm
heres some new code. what it does is accepts a base address, how many levels of pointers to go through, and offsets to add to the pointers if any. it returns the address that the last pointer leads to.

Code
DLL_EXPORT DWORD *ReadPointer(void* base, unsigned int level, ...)
{
 unsigned long *output = (unsigned long*)base;
 va_list        offsets;

 va_start(offsets, level);

 for (unsigned int i = 0; i <= level; i++)
 {
   output = ((unsigned long*)(*output + va_arg(offsets, unsigned int)));
 }

 va_end(offsets);

 return (DWORD*)output;
}


usage: PLAYER *Player_Stats = (PLAYER*)ReadPointer((void*)0x00BBC9CC, 1, 0x34);

This will take the BASE address specified, go through 2 pointers and apply 0x34 offset to the second pointer. ex: Base PTR->Next PTR+0x34->Returned Address

edit::

for example say i mapped the player counter for players in your proximity to

PPL count RBASE+0x1C+0x1C+0x20+0x14

i would do

DWORD *Local_Players = (DWORD*)ReadPointer((void*)0x00BBC26C, 4, 0x1C, 0x1C, 0x20, 0x14);

and it would load the address holding the 4 byte integer for local players in your proximity into Local_Players so you can use it as a local variable inside your DLL code.

This post was edited by AbDuCt on Mar 29 2013 10:30pm
Go Back To Programming & Development Topic List
Prev123
Closed New Topic New Poll