[HotS][0.10.0.34846] GalaxyScript Information menu

User Tag List

Results 1 to 12 of 12
  1. #1
    Midi12's Avatar Contributor
    Reputation
    90
    Join Date
    Sep 2012
    Posts
    182
    Thanks G/R
    6/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [HotS][0.10.0.34846] GalaxyScript Information

    Hello, here is some informations about the Galaxy script engine used in HotS (Galaxy scripts are also used in SC2).

    Before starting I would like to thanks @athre0z for his great tool and source about HotS unpacking which made static analysis make easier instead of using a dump

    Table of contents
    1. Preface
    2. Galaxy function registration
    3. Galaxy enumeration registration
    4. Dumping Galaxy functions
    5. Dumping Galaxy enumerations
    6. IDC Scripts
    7. Full dumps
    8. Credits


    1. Preface
    Galaxy Script as (nearly ?) every scripting language in a game context need to link his function declaration against the native function of the game.
    It is similar to Lua in WoW or WildStar, script functions names are statically embedded in the game executable.
    In this post I'm gonna explain how to dump those functions & the according enums from the native registrations functions (not the registration & script <-> native function linking and calling).

    2. Galaxy function registration
    At the beggining we need to reach the table which contains all the Galaxy functions about to be registered for the game.
    You could search for any Galaxy script function name in order to reach it, let say "GalaxyNativeInvalid" which is in fact the first entry of the table but any function name would work but you'll have to search for the beggining.

    You'll end up to something like this (some things have been renamed) :


    Looking at "GalaxyNativeInvalid" and "DebugString" we could guess the size of each entries in the registration table, which is 0x18 (1DAB0F0 - 1DAB0F0).

    I ended up with a structure for each entries :

    Code:
    #pragma pack(push, 1)
    struct __declspec(align(1)) GalaxyScriptEntry_t
    {
      int (__thiscall *funcPtr)(void *this);
      const char *Name;
      BYTE nParameters;
      BYTE returnType;
      BYTE parametersType[14];
    };
    #pragma pack(pop)
    Now, looking at the xref provided by IDA for the first field of the registration table we end up at a lone function :


    We'll use this to parse the table and dump usefull informations in a next chapter.

    3. Galaxy enumeration registration
    Unlike Galaxy functions, Galaxy enums aren't stored in a lone table and not registered from a lone function but the function which actually register each enumeration is unique.
    Like Galaxy functions, finding where is statically stored enums lead to this wanted function.

    Example of stored enum data :


    IDA output of code using those data :


    After analysing previous instruction before the call of "GalaxyEnum::Register" and the static data I was able to determine :

    Code:
    struct GalaxyEnumEntry_t
    {
      DWORD Value;
      const char *Name;
      DWORD NameLen;
    };
    Code:
    int __thiscall GalaxyEnum::Register(void *this, const char *Name, int nNameLen, const char *ShortName, int nShortNameLen, GalaxyEnumEntry_t *pEnumData, int nNumData, int nUnk, int nUnk_0, unsigned int pUnkData, int nNumUnkData, int nUnk_1, int nUnk_2);
    We'll use this in order to dump enums data.

    4. Dumping Galaxy functions
    Parsing the table is doing the job

    Code:
    auto curEntry = dwGScriptTableStart;
    do
    {
    	curEntryFuncPtr = Dword(curEntry + 0);
    	curEntryFuncName = GetString(Dword(curEntry + 4), -1, ASCSTR_C);
    	dumpFunction(hFile, curEntryFuncPtr, curEntryFuncName);
    	curEntry = curEntry + nGalaxyTableEntrySize;
    }
    while(curEntry < dwGScriptTableEnd);
    5. Dumping Galaxy enumerations
    It is more complicate here because you'll need to extract data from previous instructions before the call of "GalaxyEnum::Register" in order to dump the according static enum table.

    Extracting data :
    Code:
    auto head = PrevHead(dwAddress, 8);
    	
    //mov ecx, esi
    //mov dword_xxxxxxxx, eax
    while(GetMnem(head) == "mov")
    	head = PrevHead(head, 8);
    
    //push offset <EnumName>
    if(GetMnem(head) == "push")
    {
    	szEnumName = GetString(GetOperandValue(head, 0), -1, ASCSTR_C);
    }
    else
    {
    	Message("Unexpected instruction at %x\n", head);
    	return;
    }
    	
    //push <name lenght>
    head = PrevHead(head, 8);
    if(GetMnem(head) != "push")
    {
    	Message("Unexpected instruction at %x\n", head);
    	return;
    }
    
    //push offset <enumShortName>
    head = PrevHead(head, 8);
    if(GetMnem(head) == "push")
    {
    	szEnumShortName = GetString(GetOperandValue(head, 0), -1, ASCSTR_C);
    }
    else
    {
    	Message("Unexpected instruction at %x", head);
    	return;
    }
    
    //push <short name lenght>
    head = PrevHead(head, 8);
    if(GetMnem(head) != "push")
    {
    	Message("Unexpected instruction at %x\n", head);
    	return;
    }
    	
    //push offset <enum data>
    head = PrevHead(head, 8);
    if(GetMnem(head) == "push")
    {
    	dwEnumDataAddress = GetOperandValue(head, 0);
    }
    else
    {
    	Message("Unexpected instruction at %x", head);
    	return;
    }
    
    //push offset <enum data lenght>
    head = PrevHead(head, 8);
    if(GetMnem(head) == "push")
    {
    	nEnumData = GetOperandValue(head, 0);
    }
    else
    {
    	Message("Unexpected instruction at %x", head);
    	return;
    }
    Dumping enum :
    Code:
    for(i = 0; i < nDataLenght * 12; i = i + 12)
    {
    	dwFieldValue = Dword(dwData + i + 0);
    	szFieldName = GetString(Dword(dwData + i + 4), -1, ASCSTR_C);
    }
    6. IDC Scripts
    GalaxyScriptFunctionDumper.idc
    Code:
    #include <idc.idc>
    
    static ExtractPath( szPath )
    {
    	auto dwIndex;
    	for ( dwIndex = strlen( szPath ); strstr( substr( szPath, dwIndex, -1 ), "/" ) && dwIndex > 0; dwIndex-- );
    	return substr( szPath, 0, dwIndex + 1 );
    }
    
    static getGScriptTableStart()
    {
    	auto dwAddress;
    	dwAddress = FindBinary(dwAddress + 1, SEARCH_DOWN|SEARCH_NEXT, "56 57 33 F6 BF ?? ?? ?? ?? 8D A4");
    	
    	return Dword(dwAddress + 5);
    }
    
    static getGScriptTableEnd()
    {
    	auto dwAddress;
    	dwAddress = FindBinary(dwAddress + 1, SEARCH_DOWN|SEARCH_NEXT, "56 E8 ?? ?? ?? ?? 83 C7 ?? 46 81 FF ?? ?? ?? ??");
    	
    	return Dword(dwAddress + 12);
    }
    
    static dumpFunction( hFile, fnAddress, fnName )
    {
    	Message("[modulebase + 0x%X] : %s\n", fnAddress - 0x800000, fnName);
    	fprintf(hFile, "[modulebase + 0x%x] : %s\n", fnAddress - 0x800000, fnName);
    }
    
    static main()
    {
    	Message("[Galaxy Script Function Dumper by Midi12]\n");
    	
    	auto hFile, szPath;
    	szPath = ExtractPath(GetIdbPath()) + "GalaxyScript__FunctionDump.txt";
    	hFile = fopen(szPath, "w");
    
    	if(hFile == -1)
    	{
    		Message("Can't open dump file, aborting...");
    		return;
    	}
    	
    	fprintf(hFile, "[Galaxy Script Function Dumper by Midi12]\n");
    	fprintf(hFile, "\n");
    	
    	auto dwGScriptTableStart = getGScriptTableStart();
    	
    	Message("GalaxyScriptTableStart : %x\n", dwGScriptTableStart);
    
    	auto dwGScriptTableEnd = getGScriptTableEnd();
    	
    	Message("GalaxyScriptTableEnd : %x\n", dwGScriptTableEnd);
    
    	auto nGalaxyTableEntrySize = 24;
    	auto curEntry = dwGScriptTableStart;
    	auto curEntryFuncPtr = 0;
    	auto curEntryFuncName = 0;
    
    	auto nFunction = 0;
    	
    	do
    	{
    		curEntryFuncPtr = Dword(curEntry + 0);
    		curEntryFuncName = GetString(Dword(curEntry + 4), -1, ASCSTR_C);
    		dumpFunction(hFile, curEntryFuncPtr, curEntryFuncName);
    		curEntry = curEntry + nGalaxyTableEntrySize;
    		nFunction = nFunction + 1;
    	}
    	while(curEntry < dwGScriptTableEnd);
    
    	fprintf(hFile, "\n");
    	fprintf(hFile, "[End of dump]");
    	
    	fclose(hFile);
    	
    	Message("Functions dumped = %d\n", nFunction);
    	Message("Dump complete\n");
    }
    GalaxyScriptEnumDumper.idc
    Code:
    #include <idc.idc>
    
    static ExtractPath( szPath )
    {
    	auto dwIndex;
    	for ( dwIndex = strlen( szPath ); strstr( substr( szPath, dwIndex, -1 ), "/" ) && dwIndex > 0; dwIndex-- );
    	return substr( szPath, 0, dwIndex + 1 );
    }
    
    static IsAddrStartOfFunction( dwAddress )
    {
    	if(GetFunctionAttr(dwAddress, FUNCATTR_START) == dwAddress)
    		return 1;
    	return 0;
    }
    
    static getRegisterFunction()
    {
    	auto dwAddress;
    	dwAddress = FindBinary(dwAddress + 1, SEARCH_DOWN|SEARCH_NEXT, "55 8B EC 83 EC ?? 56 57 6A ?? 8B F9 E8 ?? ?? ?? ?? 83 C4");
    	
    	if(IsAddrStartOfFunction(dwAddress) == 0)
    		return -1;
    	else
    		return dwAddress;
    }
    
    static dumpEnumDataInternal(hFile, dwData, nDataLenght)
    {
    	auto dwFieldValue;
    	auto szFieldName;
    	
    	auto i;
    	for(i = 0; i < nDataLenght * 12; i = i + 12)
    	{
    		dwFieldValue = Dword(dwData + i + 0);
    		szFieldName = GetString(Dword(dwData + i + 4), -1, ASCSTR_C);
    		
    		Message("\tFieldName = %s\n", szFieldName);
    		Message("\tFieldValue = %d\n", dwFieldValue);
    		
    		fprintf(hFile, "\t%s = %d,\n", szFieldName, dwFieldValue);
    	}
    }
    
    static dumpEnumFromAddress( hFile, dwAddress )
    {
    	auto szEnumName;
    	auto szEnumShortName;
    	auto dwEnumDataAddress;
    	auto nEnumData;
    	
    	Message("entering dumpEnumFromAddress\n");
    	auto head = PrevHead(dwAddress, 8);
    	
    	//mov ecx, esi
    	//mov dword_xxxxxxxx, eax
    	while(GetMnem(head) == "mov")
    		head = PrevHead(head, 8);
    	
    	//push offset <EnumName>
    	if(GetMnem(head) == "push")
    	{
    		szEnumName = GetString(GetOperandValue(head, 0), -1, ASCSTR_C);
    	}
    	else
    	{
    		Message("Unexpected instruction at %x\n", head);
    		return;
    	}
    	
    	//push <name lenght>
    	head = PrevHead(head, 8);
    	if(GetMnem(head) != "push")
    	{
    		Message("Unexpected instruction at %x\n", head);
    		return;
    	}
    	
    	//push offset <enumShortName>
    	head = PrevHead(head, 8);
    	if(GetMnem(head) == "push")
    	{
    		szEnumShortName = GetString(GetOperandValue(head, 0), -1, ASCSTR_C);
    	}
    	else
    	{
    		Message("Unexpected instruction at %x", head);
    		return;
    	}
    	
    	//push <short name lenght>
    	head = PrevHead(head, 8);
    	if(GetMnem(head) != "push")
    	{
    		Message("Unexpected instruction at %x\n", head);
    		return;
    	}
    	
    	//push offset <enum data>
    	head = PrevHead(head, 8);
    	if(GetMnem(head) == "push")
    	{
    		dwEnumDataAddress = GetOperandValue(head, 0);
    	}
    	else
    	{
    		Message("Unexpected instruction at %x", head);
    		return;
    	}
    	
    	//push offset <enum data lenght>
    	head = PrevHead(head, 8);
    	if(GetMnem(head) == "push")
    	{
    		nEnumData = GetOperandValue(head, 0);
    	}
    	else
    	{
    		Message("Unexpected instruction at %x", head);
    		return;
    	}
    	
    	Message("Name = %s\n", szEnumName);
    	Message("ShortName = %s\n", szEnumShortName);
    	Message("Enum Data ptr = %x\n", dwEnumDataAddress);
    	Message("Enum Data len = %d\n", nEnumData);
    	
    	fprintf(hFile, "enum class %s //%s\n", szEnumName, szEnumShortName);
    	fprintf(hFile, "{\n");
    	
    	dumpEnumDataInternal(hFile, dwEnumDataAddress, nEnumData);
    	
    	fprintf(hFile, "}\n\n");
    	
    	return;
    }
    
    static main()
    {
    	auto hFile, szPath;
    	szPath = ExtractPath(GetIdbPath()) + "GalaxyScript__EnumDump.txt";
    	hFile = fopen(szPath, "w");
    	
    	Message("[Galaxy Script Enum Dumper by Midi12]\n");
    	
    	if(hFile == -1)
    	{
    		Message("Can't open dump file, aborting ...");
    		return;
    	}
    	
    	fprintf(hFile, "[Galaxy Script Enum Dumper by Midi12]\n");
    	fprintf(hFile, "\n");
    	
    	auto dwRegisterFunction = getRegisterFunction();
    	
    	if(dwRegisterFunction == -1)
    	{
    		Message("Can't find GalaxyEnum::Register() function, aborting ...");
    		fclose(hFile);
    		return;
    	}
    	
    	auto dwAddress = 0;
    	auto nEnums = 0;
    	
    	while(dwAddress != BADADDR)
    	{
    		dwAddress = RnextB(dwRegisterFunction, dwAddress);
    		
    		if(dwAddress == BADADDR)
    			break;
    		
    		dumpEnumFromAddress(hFile, dwAddress);
    		nEnums = nEnums + 1;
    	}
    	
    	Message("Enums dumped : %d\n", nEnums);
    	Message("Dump complete\n");
    	
    	fprintf(hFile, "\n");
    	fprintf(hFile, "[End of dump]");
    	
    	fclose(hFile);
    }
    7. Full dumps
    See second post.

    8. Credits
    • athre0z (hots static unpacking source)
    • crash_man7 (previous work on galaxy script for SC2, was able to complete my structure definition for Galaxy functions)
    • everyone who helped & still helps during my journey of self-taught in reverse engineering


    End words
    I have still to reverse the internal of script functions and add to my script the script variables arguments for each script function. I'll update my post once I did it.
    Sorry for my weird english and if you see something to modify feel free to pm me.
    92izii !

    [HotS][0.10.0.34846] GalaxyScript Information
  2. #2
    Midi12's Avatar Contributor
    Reputation
    90
    Join Date
    Sep 2012
    Posts
    182
    Thanks G/R
    6/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Last edited by Midi12; 04-22-2015 at 04:22 AM.

  3. #3
    Vengfull's Avatar War is Coming - Warmonger VPS & Hosting Services
    CoreCoins Purchaser
    Reputation
    782
    Join Date
    Jan 2012
    Posts
    662
    Thanks G/R
    162/80
    Trade Feedback
    8 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This looks majorly in depth, Great work +rep

    PS i only skim read it

  4. #4
    MileP's Avatar Member
    Reputation
    1
    Join Date
    Apr 2015
    Posts
    39
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What can you do with this script ?

  5. #5
    Miksu's Avatar Contributor
    Reputation
    244
    Join Date
    Nov 2007
    Posts
    731
    Thanks G/R
    216/25
    Trade Feedback
    5 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by MileP View Post
    What can you do with this script ?
    If you don't know what is it for then you dont need it.


  6. #6
    athre0z's Avatar Active Member
    Reputation
    17
    Join Date
    Apr 2015
    Posts
    11
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Good job. Wish I could give you some +rep, but it seems like I don't have enough rep myself for that.

    By the way: have a look at IDAPython. You will realize that you will at least double your productivity compared to IDC. IDAPy also gives you access to the whole IDA SDK using the idaapi module (on top of the IDC functions, which are also available).

  7. #7
    Midi12's Avatar Contributor
    Reputation
    90
    Join Date
    Sep 2012
    Posts
    182
    Thanks G/R
    6/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by athre0z View Post
    Good job. Wish I could give you some +rep, but it seems like I don't have enough rep myself for that.

    By the way: have a look at IDAPython. You will realize that you will at least double your productivity compared to IDC. IDAPy also gives you access to the whole IDA SDK using the idaapi module (on top of the IDC functions, which are also available).
    Yes I use IDA scripting language because I'm used to it but I already thought of moving to IDAPython.
    92izii !

  8. #8
    LWSS's Avatar Member
    Reputation
    1
    Join Date
    May 2015
    Posts
    2
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I understood everything you said, but not really familiar with galaxyscript.

    Can you call these functions? What's the anti-cheat system like on this game?

  9. #9
    Midi12's Avatar Contributor
    Reputation
    90
    Join Date
    Sep 2012
    Posts
    182
    Thanks G/R
    6/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by LWSS View Post
    Can you call these functions?
    Yes, simply call the native function like every function, prototype for native function is
    Code:
    typedef int(__thiscall *fnGalaxyNative_t)(void* this /*looks like a param's stack*/);
    I don't reversed too much the natives yet.

    Originally Posted by LWSS View Post
    What's the anti-cheat system like on this game?
    Warden variant probably.
    92izii !

  10. #10
    WHGokke's Avatar Member
    Reputation
    1
    Join Date
    May 2015
    Posts
    1
    Thanks G/R
    1/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    class CScriptManager // Size = 0x20
    {
    public:
    	void* m_pFunctionPtr; //0x0000
    	char* m_pszFunctionName; //0x0008
    	char Unknown_0x0010[ 16 ];
    };
    
    CScriptManager* g_pScriptManager = reinterpret_cast< CScriptManager* >( g_dwScriptManager );
    Code:
    namespace ScriptManager
    {
    	void* GetFunctionByName( char* szFunction )
    	{
    		for( size_t i = 0; i < 2570; i++ )
    		{
    			if( strstr( szFunction, g_pScriptManager[ i ].m_pszFunctionName ) )
    			{
    				return g_pScriptManager[ i ].m_pFunctionPtr;
    			}
    		}
    
    		return nullptr;
    	}
    
    	void DumpFunctions( )
    	{
    		for( size_t i = 0; i < 2570; i++ )
    		{
    			LOG( "[%p] %s\n", g_pScriptManager[ i ].m_pFunctionPtr, g_pScriptManager[ i ].m_pszFunctionName );
    		}
    	}
    }
    They now have a fixed size on the table, so you can just loop that. Anyone found a WorldToScreen?

  11. #11
    LWSS's Avatar Member
    Reputation
    1
    Join Date
    May 2015
    Posts
    2
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    do you guys want to make a skype group or something, I need some buddies

  12. #12
    h42's Avatar Contributor CoreCoins Purchaser
    Reputation
    130
    Join Date
    Oct 2006
    Posts
    108
    Thanks G/R
    139/52
    Trade Feedback
    12 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey, this looks way more alive compared to when I last posted a galaxyscript dump for HotS, ended up with 0 replies that time.
    Great work on that unpacker athre0z, such a quality of life improvement compared to manually dumping each new version!

    I mostly work with the 64bit client, so most of my stuff is irrelevant to binaries unpacked this way, but one easy improvement to understanding of the galaxyscript functions are to identify return/parameter types.
    I find that its way easier to reverse em with the full function declarations, so I added that to my dumping script, but digging it up from a few months ago was easier said than done.
    Did find an old text file with notes on the types, which should be mostly correct:

    Code:
     - = "void" 
     
      // types
     ? = "bool" 
     1 = "byte" 
     4 = "int" 
     3 = "fixed" 
     s = "string" 
     x = "text" 
      
      // structs
     a = "abilcmd" 
     i = "actor" 
     e = "actorscope" 
     j = "aifilter" 
     b = "bank" 
     c = "camerainfo" 
     2 = "color" 
     M = "doodad" 
     k = "effecthistory"
     q = "handle" 
     m = "marker" 
     o = "order" 
     l = "playergroup" 
     p = "point" 
     r = "region" 
     R = "revealer" 
     n = "sound" 
     d = "soundlink" 
     t = "timer" 
     y = "transmissionsource" 
     T = "trigger" 
     U = "unit" 
     f = "unitfilter" 
     u = "unitgroup" 
     v = "unitref" 
     W = "wave" 
     w = "waveinfo" 
     g = "wavetarget"
    As seen in the OP these values are simply stored in the spare bytes of the structure, so just add a look-up in the idc for each parameter/returntype.

    EDIT:
    Hacked in this ugly edit to OP's .idc for function dumps, for the lazy:
    (IDC scripts are never beautiful..)
    Code:
    #include <idc.idc>
    
    
    static ExtractPath( szPath )
    {
        auto dwIndex;
        for ( dwIndex = strlen( szPath ); strstr( substr( szPath, dwIndex, -1 ), "/" ) && dwIndex > 0; dwIndex-- );
        return substr( szPath, 0, dwIndex + 1 );
    }
    
    
    static getGScriptTableStart()
    {
        auto dwAddress;
        dwAddress = FindBinary(dwAddress + 1, SEARCH_DOWN|SEARCH_NEXT, "56 57 33 F6 BF ?? ?? ?? ?? 8D A4");
        
        return Dword(dwAddress + 5);
    }
    
    
    static getGScriptTableEnd()
    {
        auto dwAddress;
        dwAddress = FindBinary(dwAddress + 1, SEARCH_DOWN|SEARCH_NEXT, "56 E8 ?? ?? ?? ?? 83 C7 ?? 46 81 FF ?? ?? ?? ??");
        
        return Dword(dwAddress + 12);
    }
    
    
    static translateType( hFile, type )
    {
      auto name;
      
      if( type == '-' ) { name = "void"; }
      // types
      else if( type == '?' ) { name = "bool"; }
      else if( type == '1' ) { name = "byte"; }
      else if( type == '4' ) { name = "int"; }
      else if( type == '3' ) { name = "fixed"; }
      else if( type == 's' ) { name = "string"; }
      else if( type == 'x' ) { name = "text"; }
      
      // structs
      else if( type == 'a' ) { name = "abilcmd"; }
      else if( type == 'i' ) { name = "actor"; }
      else if( type == 'e' ) { name = "actorscope"; }
      else if( type == 'j' ) { name = "aifilter"; }
      else if( type == 'b' ) { name = "bank"; }
      else if( type == 'c' ) { name = "camerainfo"; }
      else if( type == '2' ) { name = "color"; }
      else if( type == 'M' ) { name = "doodad"; }
      else if( type == 'k' ) { name = "effecthistory"; } // enum?
      else if( type == 'q' ) { name = "handle"; }
      else if( type == 'm' ) { name = "marker"; }
      else if( type == 'o' ) { name = "order"; }
      else if( type == 'l' ) { name = "playergroup"; }
      else if( type == 'p' ) { name = "point"; }
      else if( type == 'r' ) { name = "region"; }
      else if( type == 'R' ) { name = "revealer"; }
      else if( type == 'n' ) { name = "sound"; }
      else if( type == 'd' ) { name = "soundlink"; }
      else if( type == 't' ) { name = "timer"; }
      else if( type == 'y' ) { name = "transmissionsource"; }
      else if( type == 'T' ) { name = "trigger"; }
      else if( type == 'U' ) { name = "unit"; }
      else if( type == 'f' ) { name = "unitfilter"; }
      else if( type == 'u' ) { name = "unitgroup"; }
      else if( type == 'v' ) { name = "unitref"; }
      else if( type == 'W' ) { name = "wave"; }
      else if( type == 'w' ) { name = "waveinfo"; }
      else if( type == 'g' ) { name = "wavetarget"; }
      else { name = "?unknown?"; }
      
      Message( "%s", name );
      fprintf(hFile, "%s", name);
    }
    
    
    static dumpFunction( hFile, curEntry, fnAddress, fnName )
    {
        auto numParams, returnType, n;
        
        numParams = Byte(curEntry + 0x8);
        returnType = Byte(curEntry + 0x9);
    
    
        Message("[modulebase + 0x%X] : ", fnAddress - 0x800000);
        fprintf(hFile, "[modulebase + 0x%x] : ", fnAddress - 0x800000);
        translateType(hFile, returnType);
        
        Message( " %s( ", fnName );
        fprintf( hFile, " %s( ", fnName );
        for( n = 0; n < numParams; n++ )
        {
            if( n > 0 )
            {
                Message( ", " );
                fprintf( hFile, ", " );
            }
            translateType( hFile, Byte( curEntry + 0xA + n ) );
        }
        Message( " )\n" );
        fprintf( hFile, " )\n" );
    }
    
    
    static main()
    {
        Message("[Galaxy Script Function Dumper by Midi12]\n");
        
        auto hFile, szPath;
        szPath = ExtractPath(GetIdbPath()) + "GalaxyScript__FunctionDump.txt";
        hFile = fopen(szPath, "w");
    
    
        if(hFile == -1)
        {
            Message("Can't open dump file, aborting...");
            return;
        }
        
        fprintf(hFile, "[Galaxy Script Function Dumper by Midi12]\n");
        fprintf(hFile, "\n");
        
        auto dwGScriptTableStart = getGScriptTableStart();
        
        Message("GalaxyScriptTableStart : %x\n", dwGScriptTableStart);
    
    
        auto dwGScriptTableEnd = getGScriptTableEnd();
        
        Message("GalaxyScriptTableEnd : %x\n", dwGScriptTableEnd);
    
    
        auto nGalaxyTableEntrySize = 24;
        auto curEntry = dwGScriptTableStart;
        auto curEntryFuncPtr = 0;
        auto curEntryFuncName = 0;
    
    
        auto nFunction = 0;
        
        do
        {
            curEntryFuncPtr = Dword(curEntry + 0);
            curEntryFuncName = GetString(Dword(curEntry + 4), -1, ASCSTR_C);
            dumpFunction(hFile, curEntry, curEntryFuncPtr, curEntryFuncName);
            curEntry = curEntry + nGalaxyTableEntrySize;
            nFunction = nFunction + 1;
        }
        while(curEntry < dwGScriptTableEnd);
    
    
        fprintf(hFile, "\n");
        fprintf(hFile, "[End of dump]");
        
        fclose(hFile);
        
        Message("Functions dumped = %d\n", nFunction);
        Message("Dump complete\n");
    }
    Last edited by h42; 05-12-2015 at 03:50 PM. Reason: Added .idc

Similar Threads

  1. [Hots] Maphack + other features! ver 1.5.410.34846
    By elitemantis in forum Heroes of the Storm Exploits, Cheats and Hacks
    Replies: 16
    Last Post: 01-09-2017, 10:26 AM
  2. [HotS][0.10.0.34846] GalaxyScript Information
    By Midi12 in forum Heroes of the Storm General
    Replies: 4
    Last Post: 04-23-2015, 10:27 AM
  3. [Hots] Maphack + other features! ver 1.5.410.34846
    By elitemantis in forum Heroes of the Storm General
    Replies: 3
    Last Post: 04-23-2015, 08:40 AM
  4. 1.11 Patch - Tonnes of Naxxramas Information!
    By Dwarpy in forum World of Warcraft General
    Replies: 3
    Last Post: 05-21-2006, 11:44 AM
  5. Hot fishing spots & fishing tips
    By Matt in forum World of Warcraft Guides
    Replies: 1
    Last Post: 03-15-2006, 02:40 AM
All times are GMT -5. The time now is 03:37 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