Importing .map info to IDA

A forum for feature requests/discussions and user submitted patches that improve MQ2

Moderator: MacroQuest Developers

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Importing .map info to IDA

Post by Lax » Wed Sep 24, 2003 5:40 pm

I don't know if there's a better solution, but this is useful a million times over. Having the testeqgame.exe open in IDA and a generated file from the .map that looks like this:
(Removed, see the info a few posts down)

This IDA script (.IDC) is used to import

Code: Select all

(Removed, see the script a few posts down)
.. save, run it in IDA, and your favorite disassembler is now loaded with comments

maybe this will help someone besides me
Last edited by Lax on Thu Sep 25, 2003 9:09 am, edited 1 time in total.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Wed Sep 24, 2003 5:53 pm

scratch that, it does have a way. I'll have an idc ready shortly ;)
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Wed Sep 24, 2003 6:17 pm

Dude, this would be really sweet.

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Wed Sep 24, 2003 6:33 pm

All set!

Step 1: Convert EQMule's .XLS to .CSV.
Step 2: Compile and run this (MFC, console) program to generate ida-import.txt for use with the IDA script (ends up a 700k or so text file):

Code: Select all

// ConvertCSV.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// The one and only application object

CWinApp theApp;

using namespace std;

CString CleanName(CString Str)
{
	// remove <x>;
	// remove (x)
	// remove extra words
	int Pos=Str.Find('<');
	while(Pos>=0)
	{
		int Len=Str.GetLength();
		int Count=0;
		for (int PosB = Pos ; PosB < Len ; PosB++)
		{
			if (Str.GetAt(PosB)=='<')
				Count++;
			else if (Str.GetAt(PosB)=='>')
			{
				Count--;
				if (Count<=0)
					break;
			}
		}
//		int PosB=Str.Find('>');
		if (PosB>0)
		{
			Str.Delete(Pos,PosB-Pos+1);
			Pos=Str.Find('<');
		}
		else
			break;
	}
	Pos=Str.Find('(');
	if (Pos>=0)
		Str=Str.Left(Pos);
	Pos=Str.ReverseFind(' ');
	if (Pos>=0)
		Str.Delete(0,Pos+1);
	Str.Replace(':','_');
	Str.Replace('~','d');
	return Str;
}

CString GetAttribute(CString Str, int N)
{
	int nAttr=0;
	int Len = Str.GetLength();
	bool quotes=false;
	CString Out;
	for (int i = 0 ; i < Len ; i++)
	{
		char c=Str.GetAt(i);
		if (c==',' && !quotes)
		{
			nAttr++;
			if (N==nAttr)
				return Out;
			Out="";
		}
		else if (c=='"')
		{
			quotes=!quotes;
		}
		else
		{
			Out.AppendChar(c);
		}
	}
	return "";
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		printf("ConvertCSV\n");
		CStdioFile InFile;
		if (!InFile.Open("c:\\path\\to\\Undecorated_testeqgame_map.csv",CFile::modeRead|CFile::shareDenyNone))
		{
			printf("Failed to open Undecorated_testeqgame_map.csv\n");
			return 0;
		}
		CStdioFile OutFile;
		if (!OutFile.Open("c:\\path\\to\\ida-import.txt",CFile::modeCreate|CFile::modeWrite|CFile::shareDenyNone))
		{
			printf("Failed to open ida-import.txt\n");
			return 0;
		}
		CString Input;
		while(InFile.ReadString(Input))
		{
			CString Output;
			CString Offset=GetAttribute(Input,4);
			CString Name=GetAttribute(Input,1);
			CString Cleaned=CleanName(Name);
			if (Offset.GetLength() 
				&& Offset.GetAt(0)=='0' 
				&& Cleaned.GetLength() 
				&& Cleaned.Find('\'')==-1
				&& Name.CompareNoCase("`string'") 
				&& Name.Find("operator")==-1 
				&& Name.Find("destructor")==-1 
				&& Name.Find("constructor")==-1 
				&& Name.Left(2).Compare("_$")
				)
			{
				Output.Format("%s %s %s\n",Offset,Cleaned,Name);
				OutFile.WriteString(Output);
			}
		}
	}

	return nRetCode;
}
which generates lines that look like THIS:
00401000 CAAWnd__CAAWnd public: __thiscall CAAWnd::CAAWnd(class CXWnd *)

address, cleaned up name, info for comment

.. now, use this IDC script in IDA:

Code: Select all

static main() {
  auto fh;
  auto stemp,sleft,smiddle,sright,pos;
  fh=fopen("c:\\path\\to\\ida-import.txt","r");
  if (fh==0)
  {
    Message("Could not open ida-import.txt\n");
    return;
  }
  Message("Beginning import map script\n");

  SetStatus(3);

  while(stemp != -1)
  {
    stemp=readstr(fh);
    if (stemp != -1)
    {
       //  01234567890 pos
       //  12345678901 len
       // "100 abcdefg"
       //      1234567
       pos=strstr(stemp," ");
       if (pos != -1)
       {
          sleft=substr(stemp,0,pos);
          // strip both the space and the \n
          smiddle=substr(stemp,pos+1,strlen(stemp)-1);
          pos=strstr(smiddle," ");
          sright=substr(smiddle,pos+1,strlen(smiddle)-1);
          smiddle=substr(smiddle,0,pos);
          MakeName(xtol(sleft),smiddle);
          MakeRptCmt(xtol(sleft),sright);
       }
    }
  }

  fclose(fh);
  SetStatus(0);
  Message("Done!\n");
}
Message boxes will likely pop up a lot saying "name already in use" because some names are duplicate.. but.. hold down the enter key for a minute and watch them fly by :)

Once it finishes, your View->Functions window has a sweet ass list of all the functions! And when you look at each function, some info on it is shown but not all of it fits.

Life got easy, wish I would have seen that leaked map earlier :twisted:
Last edited by Lax on Fri Sep 26, 2003 12:10 pm, edited 1 time in total.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Wed Sep 24, 2003 6:34 pm

I should mention this is for use with the leaked testeqgame.map and the testeqgame.exe that goes with it.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Wed Sep 24, 2003 7:30 pm

Next up, a program to convert to new offsets given the new and old files. Auto-name the newer files soon! 8)
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Jaerin
Developer
Developer
Posts: 133
Joined: Mon Mar 10, 2003 7:37 pm
Contact:

Post by Jaerin » Wed Sep 24, 2003 8:32 pm

What XLS file that eqmule posted?

Jaerin

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Wed Sep 24, 2003 9:02 pm

Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Thu Sep 25, 2003 9:21 am

I think this weekend I should have something whipped up that reads in two .ASM files from IDA.. one with known, one with unknown.. and it should be able to generate a new import map for the IDA script. It wont be able to match up some things but should work for most. I might just find a spot to put the generated import maps up for download, and make the program posted a bit better to make sure there's no duplicates, etc.

If someone has suggestions for a place to put it or wants to offer theirs (I could e-mail it or something) let me know, a zip of it would probably only be 50k.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

EqMule
Developer
Developer
Posts: 2697
Joined: Fri Jan 03, 2003 9:57 pm
Contact:

Post by EqMule » Thu Sep 25, 2003 2:28 pm

when you get it done id like a copy I can post it as well if you like on the same site as the map...
My status o/
If you like MQ2 and would like to contribute, please do. My goal is 25 donations per month.
So far I've received Image donations for this month's patches.

Bitcoin: 1Aq8ackjQ4f7AUvbUL7BE6oPfT8PmNP4Zq
Krono: PM me.
I can always use characters for testing, PM me if you can donate one.

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Thu Sep 25, 2003 7:04 pm

.. now, use this IDC script in IDA:
I hate to admit it, but I really don't know what this means :( I'm gold up to that point though!

MQSEQ
Hypocrite fag
Posts: 181
Joined: Fri Sep 19, 2003 5:18 pm

Post by MQSEQ » Thu Sep 25, 2003 7:28 pm

IDA is a disassembler that allows them to watch the memory values of EQ while playing. You would need to get IDA to use the scripts.

I don't know where you can get the IDA. The official site requires you to send an email with alot of information about who, what, why etc. etc. to get a eval copy.

Others use WH2 to do the same type of work.

Jaerin
Developer
Developer
Posts: 133
Joined: Mon Mar 10, 2003 7:37 pm
Contact:

Post by Jaerin » Thu Sep 25, 2003 8:53 pm

Actually we use IDA to see the disassebly of the application. This allows us to see all the functions in assembly that EQ uses. We can then use that to determine where in memory things should be.

WinHack you can use to see the current values in memory for the eqgame process. You can use this to verify that the values are actually there. Also with the map that people are talking about we can see the inputs and return values of various functions. This allows us to call some functions directly. There by bypassing the need for certain clicks and such.

It also allows a level of control that we haven't previously had.

Jaerin

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Thu Sep 25, 2003 9:40 pm

soooo....should I shoot for an evaluation copy of IDA ..or is it available from one of you cats somewhere ;)

You know me, I've been doing structs for a while ...but, I always use a "snapshot" of memory and dbgwin ...never really done anything with memory as it's going along.

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Thu Sep 25, 2003 10:49 pm

The way I've worked with EQ structs in the past is find a function that initializes them or copies data to them -- memset, malloc, memcpy, that sort of thing. Then you have the size of the struct. If it's a static struct in memory like current zone info, you can also find how each of the variables inside are used (float, dword, byte, etc).. which I posted for the zone info some time ago with the ZEM :) From there, I write a function that dumps that struct to file...

just my way of doing it, plenty of other valid ways.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0