Hi Guys
Today, I would like to share the use of IDAPyhton for you to do automation during your reversing some codes. There are use cases where IDAPhyton will help you so much on the process. I am gonna share one of them
The use case that I developed is to decrypt a base64 encrypted string. I wrote a simple application like below
#include <iostream>
char src[64] = { 'u','f','Y','Y','o','f','Z','H','p','x','P','V','e','G','p','7','E','s','Q','7','9','G','k','0' };
int main()
{
std::cout << "Let Statically Decrypt Base 64 RC4: ";
std::cout << src;
}
here below the code in IDA

The idea is to decrypt the string that is pointed by the offset char * src in the data segment statically without the need to run this application in debug mode.
IDAPython
IDAPython is an extended capability of IDA Pro that enable you to do scripting with python 2.7. You can script it in IDA within this box

I would suggest you code the python in another IDE (e.g pycharm) and paste them into this tiny box just for your convenience. There tons of IDA API that you can use to interact with IDA while you do your coding.
You can get it from https://www.hex-rays.com/products/ida/support/idapython_docs/
Lets Decrypt
As we know that the encryption that applied to the string is RC4 where the data is based64 so that we need to reverse it. Here below the steps
· You need to find the main function by looping the entire function that is available in IDA using API Functions()
· After you get the Main Function, you have to loop the address within this function to check the existense of encrypted string using API func = idaapi.get_func(funcAddr) func.startEA and func.endEA
· You need to find the Operation of each line that consists of “char *“
· Once it found char *, then we need to extract the sequence of string that it points to in the data segment
· once the string is extracted, then we need to do base64 decode and pass the result to RC4 decryption
All the high level above will look like this in the python code
import idautils
import idaapi
import binascii
import base64
def rc4crypt(key, data):
x = 0
box = range(256)
for i in range(256):
x = (x + box[i] + ord(key[i % len(key)])) % 256
box[i], box[x] = box[x], box[i]
x = 0
y = 0
out = []
for char in data:
x = (x + 1) % 256
y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256]))
return ''.join(out)
for funcAddr in Functions():
funcName = GetFunctionName(funcAddr) #get the list address of the function
if funcName == '_main':
func = idaapi.get_func(funcAddr) #construct the func structure
addr = func.startEA #get the start address
while addr < func.endEA: #loop untill the last address of the main funct
if idc.GetOpnd(addr, 0).find("char *") > 0: #find the instruction with char*
base64String = ""
newAddr = idc.GetOperandValue(addr, 0) #get the address of value
while True:
try:
a = idc.GetOpnd(newAddr, 0) #get the char in hex
a = a[:-1] #remove the trailing H in hex value
if len(a) == 0: #stop the the loop when the more char
break
temp = str(a.decode("hex")) #convert from hex to string
base64String = base64String + temp #append char to string
except:
break
newAddr = newAddr + 1 #increase one byte address for each loop
print "Extracted String : " + base64String #show the extracted value
message_bytes = base64.b64decode(base64String) #decode base64 the string to byte array
result = rc4crypt("Key", message_bytes) # run the RC4 decryption
print "Decrypted String : " + result #print the decrypt result
addr = idc.NextHead(addr)
Function() will return all list of the extracted function address that has been analyzed by IDA
GetFunctionName(functionAddress) will return the function name. The parameter of this function is functionAddress
idc.GetOpnd(Address, 0) will return the operand of each line address in the a function of address supplied. You can specify the first operand of second operand in each instruction by specifying the second parameter in the function for example mov ecx, 30h
1. idc.GetOpnd(Address, 0) will return ecx
2. idc.GetOpnd(Address, 1) will return 30h
idc.GetOperandValue(addr, 0) will return the value of the operand it points to. We will use this API to return the value from the data segment
idc.NextHead(addr) will give you the next address of the current. It helps us to loop sequence of address.
The above code will not work when the string has been change to array by IDA which is like this

You have to change it to data so that each char will have the its own address by following this steps below

After you changed them into data then the view will become like this

Now you can paste the code above into IDA script and press enter twice


We can above when the script is run then it will do the decryption as highlighted above.
We have successfully decrypted the string without having to run the application in debug mode.