Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 01-07-2006, 21:55
softworm softworm is offline
Friend
 
Join Date: Feb 2004
Posts: 43
Rept. Given: 2
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 0
Thanks Rcvd at 1 Time in 1 Post
softworm Reputation: 0
Need help about IDA plugin writing

Need help about IDA plugin writing

I'm a newbie to write IDA plugin. I'm reading a packer's code,there are
so many junkcodes so i decide to write a plugin to clear them.

for example.

Code:
011D320D 87 F5			xchg    esi, ebp
011D320F F7 D6			not     esi
011D3211 87 F5			xchg    esi, ebp
011D3213 F7 D5			not     ebp
Obviously they can be replaced by 8 nops. The problem is,they might be separated
by some more "basic" junkcode such as "lea ebp,[ebp]" or "jmp" like this:

Code:
xchg	esi,ebp
				not	esi
				jmp	xxxxxxxx
		xxxxxxxx:
				
				xchg	esi,ebp
				not	ebp
So i wrote some codes like this(a simplified version).


Code:
StripAtomicGarbage(nVAFrom,nVATo);	// This one replaces something like "lea ebp,[ebp]" with nops
StripDiscreteGarbage(nVAFrom,nVATo);

typedef struct _INSTRUCTION_INFO
{
	ea_t	address;	
	int	size;				
}INSTRUCTION_INFO, *PINSTRUCTION_INFO;


void StripDiscreteGarbage(ea_t nVAFrom,ea_t nVATo)
{
	
	DWORD		dwCurrAddr	= 0;
	BYTE		opcode		= 0;
	DWORD		dwSkip		= 0;
	
	dwCurrAddr = nVAFrom;
	while(dwCurrAddr < nVATo)
	{
		dwSkip = 0;
		
		// At first i called isCode but many junkcodes
		// were skipped.

		opcode = get_byte(dwCurrAddr);

		switch(opcode)	
		{
		case 0x87:	// xchg reg32,reg32
			dwSkip = Garbage_Xchg(dwCurrAddr);
			break;
		
		......

		default:
			break;
		}
		
		if(dwSkip)	
		{
			dwCurrAddr += dwSkip;
		}
		else
		{
			dwCurrAddr ++;
		}
	}
}

DWORD Garbage_Xchg(ea_t lpCurrOpcode)
{
	BYTE				data[8];				
	INSTRUCTION_INFO		InstrInfo[4];				
	DWORD				dwNumOfItem		= 0;
	DWORD				dwSkip			= 0;
	DWORD				dwBytesBeforeJmp	= 0;	
	
	
	if(Intelli_GetManyBytes(lpCurrOpcode,data,8,InstrInfo,dwNumOfItem,dwBytesBeforeJmp))
	{
		if((0xF7 == data[2]) && (0x87 == data[4]) && (0xF7 == data[6]))	// pattern matched?
		{
			Intelli_Nop(InstrInfo,dwNumOfItem);
			dwSkip = dwBytesBeforeJmp;
			nNumOfDiscreteJunk++;
		}
	}

	return dwSkip;
}

bool Intelli_GetManyBytes(ea_t lpStartAddr,			// start address
			  PBYTE lpBuff,				// result
			  int nSize,				// bytes to get
			  PINSTRUCTION_INFO lpInstrInfo,	// result,save instruction info
			  DWORD & dwNumOfItem,			// number of items in lpInstrInfo
			  DWORD & dwSkip)			// bytes occupied(not including ones after jmp)
{	
	// read bytes specified at lpStart,skip nops & jmp

	bool		bRet			= FALSE;
	bool		bJmpPresent		= FALSE;		
	int		nCounter		= 0;			
	ea_t		lpCurrOpcode		= 0;
	int		nInstrLen		= 0;			
	xde_instr	instruction;
	BYTE		tmp[0xA];						
	
	
	dwNumOfItem = 0;
	dwSkip = 0;
	lpCurrOpcode = lpStartAddr;

	while(TRUE)
	{
		get_many_bytes(lpCurrOpcode,tmp,0x10);		// read 10 bytes each time

		// sorry i'm not familar with IDA SDK so i used XDE instead.

		nInstrLen = xde_disasm(tmp,&instruction);
		
		if(0 == nInstrLen)
		{
			msg("Failed to analysis the code at %08X\n",lpCurrOpcode);
			break;	
		}

		if((1 == nInstrLen) && (0x90 == instruction.opcode))	// skip nops
		{
			lpCurrOpcode ++;

			if(!bJmpPresent)
			{
				dwSkip ++;
			}

			continue;
		}

		if((5 == nInstrLen) && (0xE9 == instruction.opcode))	// if jmp,continue at the destination
		{
			lpCurrOpcode = lpCurrOpcode + 5 + instruction.data_d[0];

			if(!bJmpPresent)
			{
				dwSkip += 5;
				bJmpPresent = TRUE;
			}
			
			continue;
		}

		
		if(nInstrLen <= (nSize - nCounter))
		{
			memcpy(lpBuff + nCounter,tmp,nInstrLen);
			
			lpInstrInfo->address = lpCurrOpcode;
			lpInstrInfo->size = nInstrLen;
			lpInstrInfo ++;
			dwNumOfItem ++;

			lpCurrOpcode += nInstrLen;
			nCounter += nInstrLen;

			if(!bJmpPresent)
			{
				dwSkip += nInstrLen;
			}

			continue;
		}
		else
		{
			if((nSize - nCounter) > 0)
			{
				memcpy(lpBuff + nCounter,tmp,nSize - nCounter);
			}
			
			bRet = TRUE;
			break;
		}
	}	
			  
	return bRet;
}
and a similar function named Intelli_Nop to clear the junkcodes,all i want is to nop all
junkcodes even if they are separated by "lea ebp,[ebp]" or "jmp".

But,when i run the plugin,I always get some exception like
"Access violation at address 011D2348,Read of address 011D2348." and the plugin
can't continue anymore(it has already found and cleared several junkcodes).

When exited IDA,the database was crashed. It seemed to be caused by
the call to get_many_bytes in Intelli_GetManyBytes,if i use try-catch block
i caught nothing. I wrote it with VC6.

So what's my problem? thanks in advance and forgeive my poor english.
Reply With Quote
  #2  
Old 01-09-2006, 08:55
softworm softworm is offline
Friend
 
Join Date: Feb 2004
Posts: 43
Rept. Given: 2
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 0
Thanks Rcvd at 1 Time in 1 Post
softworm Reputation: 0
I've found the reason,it's caused by my stupid fault.

I declined an arrary of type INSTRUCTION_INFO of size 4 to save the instruction information for the junkcode in my code list,so when the function Intelli_GetManyBytes read the bytes of specified size(8 bytes here),it can include more than 4 instructions and exceed the array.

sorry to disturb and thanks.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bringing IDA PRO plugin writing into 2014 Storm Shadow Source Code 1 07-04-2014 01:47
Writing 4 bytes to COM Port AgentSmith General Discussion 3 04-08-2005 01:25
writing my own OS.....where to start from?? loman General Discussion 33 06-29-2004 18:09


All times are GMT +8. The time now is 09:45.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX
( 1998 - 2021 )