Source Code My First IDC Script

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,185
78,998
2,399
IDC is the scripting language for IDA you can execute them in IDA to increase the effectiveness of your analysis.

I ran into a problem with quake3 engine, when it interprets the virtual machine byte code and compiles it into memory, it defines it as DATA instead of CODE and IDA can't find the functions because IDA doesn't understand how the virtual machine works.

So here is my first script to change virtual machine code from DATA to CODE and to find all the functions:
C++:
#include <idc.idc>

static RenameSegs(address, name)
{
	if (name == 0x75)
	{
		RenameSeg(address, "VM_UI");
		print("VM_UI Renamed");
		return;
	}

	else if (name == 0x63)
	{
		RenameSeg(address, "VM_CGAME");
		print("VM_CGAME Renamed");
		return;
	}

	else if (name == 0x71)
	{
		RenameSeg(address, "VM_QAGAME");
		print("VM_QAGAME Renamed");
		print("VM_QAGAME Found = Local Game");
		return;
	}

	else print("No VM_QAGAME Found = Multiplayer");
}

static FindCodeAndFunctions(address, codelength)
{
	auto start = SegStart(address);
	auto endCode = start + codelength;
	auto current = start;
	auto s = sprintf("SegmentStart = 0x%X", start);
	print(s);
	s = sprintf("SegmentEnd = 0x%X", endCode);
	print(s);

	while (current <= endCode)
	{

		auto length = MakeCode(current);
		if (length > 0)
		{
			s = sprintf("Coderized 0x%X", current);
			print(s);
			s = sprintf("Length = 0x%X", length);
			print(s);
			current = current + length;
		}
		else
		{
			s = sprintf("MakeCode Failed @ 0x%X", current);
			print(s);
			current = current + 0x1;
		}
	}
	print("Coderization Complete");

	current = start;
	while (current < endCode)
	{
		auto function = FindBinary(current, SEARCH_DOWN, "81 EE ?? 00 00 00 83 C7 04");

		if (function == BADADDR)
		{
			print("No Function Patterns Found");
			return;
		}

		if (function > endCode)
		{
			print("Functionator Complete");
			return;
		}

		else
		{
			auto ret = FindBinary(function, SEARCH_DOWN, "C3");
			auto success = MakeFunction(function, ret);

			if (success == 0)
			{
				s = sprintf("MakeFunction Failed @ 0x%X", function);
				print(s);
				current = function + 1;
			}
			if (success != 0)
			{
				s = sprintf("Function Created @ 0x%X", function);
				print(s);
				current = function + 1;
			}
		}
	}
}


static main()
{
	auto vm0 = 0x01F65150;
	auto vm0name = Byte(vm0 + 0x08);
	auto vm0codeBase = Dword(vm0 + 0x5c);
	auto vm0CodeLength = Dword(vm0 + 0x60);
	RenameSegs(vm0codeBase, vm0name);

	auto vm1 = vm0 + 0x94;
	auto vm1name = Byte(vm1 + 0x08);
	auto vm1codeBase = Dword(vm1 + 0x5c);
	auto vm1codeLength = Dword(vm1 + 0x60);
	RenameSegs(vm1codeBase, vm1name);

	auto vm2 = vm1 + 0x94;
	auto vm2name = Byte(vm2 + 0x08);
	auto vm2codeBase = Dword(vm2 + 0x5c);
	auto vm2codeLength = Dword(vm2 + 0x60);
	RenameSegs(vm2codeBase, vm2name);

	FindCodeAndFunctions(vm0codeBase, vm0CodeLength);
	FindCodeAndFunctions(vm1codeBase, vm1codeLength);
	//FindCodeAndFunctions(vm2codeBase, vm2codeLength);
	return 0;
}
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,298
37,938
269
protip: screenea() ( or is it screen_ea() or just ea()? i forget. ) gets whatever you've currently selected, so instead of hardcoding it, you can click a line and then execute your script, you'd probably wnat to feed it an end position too, you can do that with a popup ( forgot the name ), and then its completely portable :)

Not sure what FindData does, seems like it does some iteration, since you arent incrementing current anywhere, you could also just step over every byte if that tickles your fancy
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,185
78,998
2,399
I updated the script in the first post. It finds all the functions but I still have to figure out how to define the calling convention of the functions so they decompile nice. This is what the decompilation looks like as of right now
C++:
int __usercall sub_14510622@<eax>(int a1@<edi>, int a2@<esi>)
{
  int v2; // esi@1
  int v3; // edi@1
  int v4; // edi@1

  v2 = a2 - 24;
  v3 = a1 + 4;
  *(int *)((char *)&dword_59A1708 + v2) = *(int *)((char *)&dword_59A1700 + v2 + 32);
  *(_DWORD *)v3 = v2 + 16;
  v3 += 4;
  *(_DWORD *)v3 = 14345;
  *(int *)((char *)&dword_59A1700 + v2) = 685;
  asmCallPtr();
  *(int *)((char *)&dword_59A1700 + *(_DWORD *)(v3 - 4)) = *(_DWORD *)v3;
  v3 -= 4;
  *(int *)((char *)&dword_59A1708 + v2) = *(int *)((char *)&dword_59A1700 + v2 + 16);
  *(_DWORD *)v3 = v2 + 20;
  v3 += 4;
  *(_DWORD *)v3 = 4284;
  *(int *)((char *)&dword_59A1700 + v2) = 705;
  asmCallPtr();
  *(int *)((char *)&dword_59A1700 + *(_DWORD *)(v3 - 4)) = *(_DWORD *)v3;
  v3 -= 4;
  *(_DWORD *)v3 = *(int *)((char *)&dword_59A1700 + v2 + 20);
  v3 += 4;
  *(_DWORD *)v3 = 0;
  v4 = v3 - 8;
  if ( *(_DWORD *)(v4 + 4) == *(_DWORD *)(v4 + 8) )
  {
    *(int *)((char *)&dword_59A1708 + v2) = *(int *)((char *)&dword_59A1700 + v2 + 32);
    *(int *)((char *)&dword_59A170C + v2) = *(int *)((char *)&dword_59A1700 + v2 + 36);
    *(_DWORD *)(v4 + 4) = -4;
    *(int *)((char *)&dword_59A1700 + v2) = 744;
    asmCallPtr();
    JUMPOUT(locret_1451071E);
  }
  return off_5AA3320();
}
Not exactly correct, but making progress. Need helpz0r from the haxxing gods
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods