Pages: 1 [2]
Author Topic: How to patch in code changes  (Read 89299 times)
hackish
Full Member
***

Karma: +1/-1
Offline Offline

Posts: 56


« Reply #15 on: October 20, 2015, 07:36:38 AM »

I tried this and it worked great. Thank you.

To expand on the original topic, can we discuss deleting unused functions to reclaim space and repurposing that space for new, custom functions? I've done it with SLS and am currently deleting DSLSLRS.

My concern is identifying if deleted function was called or was part of the main runtime loop and how to handle either case with new functions. i.e. if a want to write a called function in the place of a runtime loop function that gets ran all the time.

You can easily just write a stub patch. Replace the function call with a branch to your stub, make the function call along with whatever extra function you want, then jump back to the instruction after the branch. In high level code it's the equivalent of using a couple of GOTO's. For your patches you're better off to follow the ABI so you can write the patches in C rather than assembler. It's far more productive and a good C compiler makes all sorts of messy optimizations without you having to think about it.
Logged
dream3R
Hero Member
*****

Karma: +18/-8
Offline Offline

Posts: 1194


« Reply #16 on: December 27, 2015, 08:57:57 PM »

Thanks guys. So, to be safe I should [-r0] all Registies used in a new function at the beginning and then [+r0] then back at the end?

Does this sound unreasonable? 

Think of it as pop and push (stack)
Logged



How to work out values from an A2L Smiley

http://nefariousmotorsports.com/forum/index.php?topic=5525.msg52371#msg52371


Starting Rev's http://nefariousmotorsports.com/forum/index.php?topic=5397.msg51169#msg51169

noobs read this before asking http://nefariousmotorsports.com/forum/index.php?topic=9014.0title=


ORGORIGINAL 05 5120 creator for Volvo
ORIGINAL Datalogger (Freeware) Author
ORGINAL finder of the 'extra' torque' limits
I don't have ME7.01 A2L I just use ID
flamy
Full Member
***

Karma: +6/-0
Offline Offline

Posts: 56


« Reply #17 on: December 28, 2015, 12:39:53 AM »

I also started with IDA Pro a few days ago to try out some code changes.
Is there any possibility to mass-rename adresses?

ME7Info is able to extract lots of RAM variables from a binary.
It would be nice to import them to IDA Pro.
Logged
dream3R
Hero Member
*****

Karma: +18/-8
Offline Offline

Posts: 1194


« Reply #18 on: December 28, 2015, 01:37:29 AM »

I also started with IDA Pro a few days ago to try out some code changes.
Is there any possibility to mass-rename adresses?

ME7Info is able to extract lots of RAM variables from a binary.
It would be nice to import them to IDA Pro.

I think everyone want a python script to-do that, give it a shot?
Logged



How to work out values from an A2L Smiley

http://nefariousmotorsports.com/forum/index.php?topic=5525.msg52371#msg52371


Starting Rev's http://nefariousmotorsports.com/forum/index.php?topic=5397.msg51169#msg51169

noobs read this before asking http://nefariousmotorsports.com/forum/index.php?topic=9014.0title=


ORGORIGINAL 05 5120 creator for Volvo
ORIGINAL Datalogger (Freeware) Author
ORGINAL finder of the 'extra' torque' limits
I don't have ME7.01 A2L I just use ID
TijnCU
Hero Member
*****

Karma: +60/-4
Offline Offline

Posts: 690


flying brick


« Reply #19 on: December 28, 2015, 01:46:49 AM »

You can write them into the disassembly with this AutoIt script from prj.
Logged

dream3R
Hero Member
*****

Karma: +18/-8
Offline Offline

Posts: 1194


« Reply #20 on: December 30, 2015, 06:59:56 PM »

You can easily just write a stub patch. Replace the function call with a branch to your stub, make the function call along with whatever extra function you want, then jump back to the instruction after the branch. In high level code it's the equivalent of using a couple of GOTO's. For your patches you're better off to follow the ABI so you can write the patches in C rather than assembler. It's far more productive and a good C compiler makes all sorts of messy optimizations without you having to think about it.

Like the idea dude.   There's a few empty ones in most code (stubs)
Logged



How to work out values from an A2L Smiley

http://nefariousmotorsports.com/forum/index.php?topic=5525.msg52371#msg52371


Starting Rev's http://nefariousmotorsports.com/forum/index.php?topic=5397.msg51169#msg51169

noobs read this before asking http://nefariousmotorsports.com/forum/index.php?topic=9014.0title=


ORGORIGINAL 05 5120 creator for Volvo
ORIGINAL Datalogger (Freeware) Author
ORGINAL finder of the 'extra' torque' limits
I don't have ME7.01 A2L I just use ID
Khendal
Full Member
***

Karma: +9/-8
Offline Offline

Posts: 226


« Reply #21 on: December 18, 2016, 03:07:02 PM »

I'm interesenting to apply a patch code...but i need first to disassembly the bin file...

i have this one :

Seat Leon Cupra R 1.8T BAM 225HP ME7.5 1ML906032A 0261208221 367220

Could you please advice me which settings i need to use with IDA pro?
Thanks
 
Logged
TijnCU
Hero Member
*****

Karma: +60/-4
Offline Offline

Posts: 690


flying brick


« Reply #22 on: March 14, 2018, 11:36:35 AM »

A summary of options to code in IDA:

- You can go to hex-view and press F2 to manually write code.
- you can use the patch functionality (edit>patch program>byte/word/assemble), in the patch byte function you can paste 16 bytes at a time. For most smaller functions this works quite well.
In my IDA version 6.1, patch code was not enabled. I manually enabled it by going to IDA\cfg\>idagui.cfg and look for patch submenu and set it to YES.
- You can import a bin file to a specific offset: go to File>Load file>Additional binary file... Leave "loading segments" empty, fill in the correct offset in "Loading Offset" (for example 0x8F0000) and uncheck Create segments to load it directly into your project.
« Last Edit: March 18, 2018, 08:04:49 AM by TijnCU » Logged

totti
Full Member
***

Karma: +15/-29
Offline Offline

Posts: 227


« Reply #23 on: August 07, 2021, 01:12:23 PM »

Hi,

If I would like to add a custom code which has to changes more variables what is the best solution? 1 function which contains all of the variable changes and link every original variable change to the function or have more functions which are just changes only 1 variable and link the specified variable changes to the functions.
Maybe I give a short example: For pops and bangs I changes only zwout and fuel cut. I have 2 functions 1 is for zwout changes 1 is for fuel cut. I found 3 zwout chang functions in the original code and I changed these movb commands to call with the cutom function address. I also found fuel cut movb and changed it to the custom function.

Now I think about the merge the 2 functions and link all of the relevant movb commands.
Logged
prometey1982
Sr. Member
****

Karma: +72/-60
Offline Offline

Posts: 325



WWW
« Reply #24 on: September 11, 2022, 06:58:08 AM »

Slightly modified prj's Python code for loading a2l
It's also define constants and bitfield enums and assign adress to it.

Code:
import idc
import idaapi

def processrom(min, max):
if min > 0:
min = min - 1
curaddr = idc.FindUnexplored(min, idc.SEARCH_DOWN)
while curaddr < max:
if idc.MakeFunction(curaddr) != True:
idc.MakeCode(curaddr)
curaddr = idc.FindUnexplored(curaddr, idc.SEARCH_DOWN)

return

def a2l(filename):
lastvarname = ""
lastaddress = ""
with open(filename) as fp:
                f = fp.read()
measurements = f.split("/begin MEASUREMENT")
measurements.pop(0)
print("Found: %d measurement(s)" % len(measurements))
for m in measurements:
namefound = 0
addrfound = 0
name = ""
addr = ""
                        is_enum = False
                        bit_mask = 0
for l in m.split("\n"):
l = l.strip()
if (len(l) > 0):
if (namefound == 0):
name = l
namefound = 1
                                        elif (l.startswith("BIT_MASK")):
                                                is_enum = True
                                                bit_mask = int(l.split(" ")[1], 16)
elif (l.startswith("ECU_ADDRESS")):
addr = l[12:]
addrfound = 1
break
if (addrfound != 1):
print("ERROR")
                        elif (is_enum):
                                enum_name = "enum_" + addr[2:]
                                enum_id = idc.GetEnum(enum_name)
                                if (enum_id == 4294967295L):
                                        enum_id = idc.AddEnum(-1, enum_name, 0)
                                        idc.OpEnumEx(int(addr, 0), -1, enum_id, 0)
                                        idc.MakeNameEx(int(addr, 0), "", 0)
                                if (not idc.IsBitfield(enum_id)):
                                        idc.SetEnumBf(enum_id, 1)
                                idc.AddConstEx(enum_id, name, bit_mask, bit_mask)
else:
idc.MakeNameEx(int(addr, 0), name, 1)
characteristics = f.split("/begin CHARACTERISTIC")
characteristics.pop(0)
print("Found: %d characteristics(s)" % len(characteristics))
for m in characteristics:
namefound = 0
addrfound = 0
name = ""
addr = ""
                        is_enum = False
                        bit_mask = 0
for l in m.split("\n"):
l = l.strip()
if (len(l) > 0):
if (namefound == 0):
name = l
namefound = 1
elif (l.startswith("/begin IF_DATA ETK")):
                                                addr = l.split(" ")[5]
#addr = l[28:7]
addrfound = 1
break
if (addrfound != 1):
print("ERROR", name)
else:
                                idc.MakeUnknown(int(addr, 0), 1, idaapi.DOUNK_SIMPLE)
idc.MakeNameEx(int(addr, 0), name, 1)
return
Logged

Россия - Великая страна!
https://youtu.be/fup5GzIFdXk
sonflasch
Full Member
***

Karma: +12/-2
Offline Offline

Posts: 69


« Reply #25 on: October 23, 2022, 05:56:29 AM »

Slightly modified prj's Python code for loading a2l
It's also define constants and bitfield enums and assign adress to it.

Code:
import idc
import idaapi

def processrom(min, max):
if min > 0:
min = min - 1
curaddr = idc.FindUnexplored(min, idc.SEARCH_DOWN)
while curaddr < max:
if idc.MakeFunction(curaddr) != True:
idc.MakeCode(curaddr)
curaddr = idc.FindUnexplored(curaddr, idc.SEARCH_DOWN)

return

def a2l(filename):
lastvarname = ""
lastaddress = ""
with open(filename) as fp:
                f = fp.read()
measurements = f.split("/begin MEASUREMENT")
measurements.pop(0)
print("Found: %d measurement(s)" % len(measurements))
for m in measurements:
namefound = 0
addrfound = 0
name = ""
addr = ""
                        is_enum = False
                        bit_mask = 0
for l in m.split("\n"):
l = l.strip()
if (len(l) > 0):
if (namefound == 0):
name = l
namefound = 1
                                        elif (l.startswith("BIT_MASK")):
                                                is_enum = True
                                                bit_mask = int(l.split(" ")[1], 16)
elif (l.startswith("ECU_ADDRESS")):
addr = l[12:]
addrfound = 1
break
if (addrfound != 1):
print("ERROR")
                        elif (is_enum):
                                enum_name = "enum_" + addr[2:]
                                enum_id = idc.GetEnum(enum_name)
                                if (enum_id == 4294967295L):
                                        enum_id = idc.AddEnum(-1, enum_name, 0)
                                        idc.OpEnumEx(int(addr, 0), -1, enum_id, 0)
                                        idc.MakeNameEx(int(addr, 0), "", 0)
                                if (not idc.IsBitfield(enum_id)):
                                        idc.SetEnumBf(enum_id, 1)
                                idc.AddConstEx(enum_id, name, bit_mask, bit_mask)
else:
idc.MakeNameEx(int(addr, 0), name, 1)
characteristics = f.split("/begin CHARACTERISTIC")
characteristics.pop(0)
print("Found: %d characteristics(s)" % len(characteristics))
for m in characteristics:
namefound = 0
addrfound = 0
name = ""
addr = ""
                        is_enum = False
                        bit_mask = 0
for l in m.split("\n"):
l = l.strip()
if (len(l) > 0):
if (namefound == 0):
name = l
namefound = 1
elif (l.startswith("/begin IF_DATA ETK")):
                                                addr = l.split(" ")[5]
#addr = l[28:7]
addrfound = 1
break
if (addrfound != 1):
print("ERROR", name)
else:
                                idc.MakeUnknown(int(addr, 0), 1, idaapi.DOUNK_SIMPLE)
idc.MakeNameEx(int(addr, 0), name, 1)
return


Hello all
I use the code from prometey1982 so far without any problems.

now i have another a2l which looks a little different.
here as an example:
Code:
/begin MEASUREMENT B_dslvh 
 "Bedingung Ladedrucksensor vorhanden"
 UWORD
 B_TRUE
 1
 100
 0.0
 255.0
 /begin IF_DATA DIM_X
  KP_BLOB 0xFD00 INTERN BYTE 
 /end IF_DATA
 /begin IF_DATA MCMESS
 
  KP_BLOB 0xFD00 INTERN 
 /end IF_DATA
 BIT_MASK 0x8000
/end MEASUREMENT

I have rewritten the code so far and everything works except for the ENUMS entry (it does not write ENUMS as a list).
he writes eg the enum mentioned above as a single measured value
(all others under the address will be ignored)

someone an idea? thanks for any hint

Code:
#Load a2l = a2l("C:\my.a2l")
import idc
import idaapi

def processrom(min, max):
if min > 0:
min = min - 1
curaddr = idc.FindUnexplored(min, idc.SEARCH_DOWN)
while curaddr < max:
if idc.MakeFunction(curaddr) != True:
idc.MakeCode(curaddr)
curaddr = idc.FindUnexplored(curaddr, idc.SEARCH_DOWN)

return

def a2l(filename):
lastvarname = ""
lastaddress = ""
with open(filename) as fp:
                f = fp.read()
measurements = f.split("/begin MEASUREMENT")
measurements.pop(0)
print("Found: %d measurement(s)" % len(measurements))
for m in measurements:
namefound = 0
addrfound = 0
name = ""
addr = ""
                        is_enum = False
                        bit_mask = 0
for l in m.split("\n"):
l = l.strip()
if (len(l) > 0):
if (namefound == 0):
name = l
namefound = 1
                                        elif (l.startswith("BIT_MASK")):
                                                is_enum = True
                                                bit_mask = int(l.split(" ")[1], 16)
elif (l.startswith("KP_BLOB")):
#addr = l[12:]
#print(l)
addr = l
addr = addr.replace("EXTERN","")
addr = addr.replace("WORD","")
addr = addr.replace("BYTE","")
  addr = addr.replace("LONG","")                       
addr = addr.replace("DP_BLOB","")
addr = addr.replace("KP_BLOB","")
addr = addr.replace("INDIRECT","")
addr = addr.replace(" ","")
addr = addr.replace("INTERN","")
addr = addr.replace("EXTERN","")
addr = addr.replace("IN","")
addr = addr.replace("DIRECT","")
#print(addr)
addrfound = 1
break
if (addrfound != 1):
print("ERROR")
                        elif (is_enum):
                                enum_name = "enum_" + addr[2:]
                                enum_id = idc.GetEnum(enum_name)
                                if (enum_id == 4294967295L):
                                        enum_id = idc.AddEnum(-1, enum_name, 0)
                                        idc.OpEnumEx(int(addr, 0), -1, enum_id, 0)
                                        idc.MakeNameEx(int(addr, 0), "", 0)
                                if (not idc.IsBitfield(enum_id)):
                                        idc.SetEnumBf(enum_id, 1)
                                idc.AddConstEx(enum_id, name, bit_mask, bit_mask)
else:
idc.MakeNameEx(int(addr, 0), name, 1)
characteristics = f.split("/begin CHARACTERISTIC")
characteristics.pop(0)
print("Found: %d characteristics(s)" % len(characteristics))
for m in characteristics:
namefound = 0
addrfound = 0
name = ""
addr = ""
                        is_enum = False
                        bit_mask = 0
for l in m.split("\n"):
l = l.strip()
if (len(l) > 0):
if (namefound == 0):
name = l
namefound = 1
elif (l.startswith("DP_BLOB DIRECT")):
                                                addr = l
                                                addr = addr.replace("DP_BLOB DIRECT","")
#addr = l[18:7]
addrfound = 1
break
if (addrfound != 1):
print("ERROR", name)
else:
                                idc.MakeUnknown(int(addr, 0), 1, idaapi.DOUNK_SIMPLE)
idc.MakeNameEx(int(addr, 0), name, 1)
return

Logged
nickapb2.7
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 1


« Reply #26 on: January 23, 2025, 05:46:14 PM »

Hello.  Sorry to bump an old thread but this seemed like the best place to ask.  This is might be a stupid question and I'm embarrassed to ask.  I don't have any reverse engineering/assembly code etc experience but I find this fascinating.  My question is: how does someone know where to link-in a new function?

Looking at M-box and NLS.  There are several occurrences of F3 F8 __ __ D7 40 06 02 03 F8  The original file has F3 F8 F3 8A (movb    rl4, byte_380AF3) and is changed to DA 88 00 E8 (calls   88h, sub_88E800) at address 88B3A6.  How is it figured out that this is where to put the link-in, out of anywhere in the code?

Thank you
Logged
fknbrkn
Hero Member
*****

Karma: +192/-24
Offline Offline

Posts: 1483


mk4 1.8T AUM


« Reply #27 on: January 24, 2025, 11:51:41 AM »

Hello.  Sorry to bump an old thread but this seemed like the best place to ask.  This is might be a stupid question and I'm embarrassed to ask.  I don't have any reverse engineering/assembly code etc experience but I find this fascinating.  My question is: how does someone know where to link-in a new function?

Looking at M-box and NLS.  There are several occurrences of F3 F8 __ __ D7 40 06 02 03 F8  The original file has F3 F8 F3 8A (movb    rl4, byte_380AF3) and is changed to DA 88 00 E8 (calls   88h, sub_88E800) at address 88B3A6.  How is it figured out that this is where to put the link-in, out of anywhere in the code?

Thank you

NLS routine operates with coil dwell time (tsrldyn) so the key is to find where tsrldyn getting its value and call to your routine to operate tsrldyn different ways
but as you can see there are multiple instances of writing to tsrldyn so the author finds a place right after all of them, free of JMPRs range so this code should be executed anyway. Also you shoul care about registers data coming from the original routine i.e:

mov r5, tmot_w
mov r4, nmot_w
calls my_routine ;take care about r4, r5 data in your routine as its all global registers in me7 and theyre used after your code execution to feed *_meow variables
mov nmot_meow, r4
mov tmot_meow, r5

Logged
Pages: 1 [2]
  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Page created in 0.037 seconds with 17 queries. (Pretty URLs adds 0.001s, 0q)