OpenWrt Forum Archive

Topic: TP-LINK WR702n (how to modify firmware from chinese to english ?)

The content of this topic has been archived between 25 Mar 2018 and 29 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

This has the decompressed part of boot as the StartAddr and is a bit crude. I've been playing with mips code for another type of box and have some other routines to find unicode strings, to find data refs in the data section that point to the code section but did not use them for the 702 code. The jump table routine is not used either--that is a hold over from a previous mips disassembly.

#include "IDC.IDC"

static main(void)
{
auto StartAddr, EndAddr;
StartAddr=0x80400000;
EndAddr = 0x8049b530;

if(!(EndAddr==BADADDR))
{
//MakeRptCmt(EndAddr,"EndAddr string");
find_addiu(StartAddr,EndAddr);
//find_jtable(StartAddr,EndAddr);
MakeStrings(StartAddr,EndAddr);
}
}

static find_addiu(StartAddr,EndAddr)
{
auto temp1, t0,t1;
temp1=StartAddr;

while(temp1<EndAddr-3)
{
t0 = Dword(temp1);
t0 = t0 & 0xFFFFFC00;
if((temp1>StartAddr)&&(temp1<EndAddr)&&(t0==0x27BDFC00))
    {
    MakeCode(temp1);
        Wait();
        }
temp1=temp1+4;
}
}

static find_jtable(StartAddr,EndAddr)
{
auto temp1, t0,t1,t,t2;
temp1=StartAddr+4;
t=0;
while(temp1<EndAddr-3)
{
t0=Dword(temp1-4);
t1=Dword(temp1);
t2=Dword(temp1+4);
if ((temp1>StartAddr)&&(temp1<EndAddr)&&(t1==0x00200008)&&(t0==0)&&(t2==0)&&(Byte(temp1+8)==0x80))
    {
    if(t==0){temp1=temp1+8;}
    t=1;
    while(Byte(temp1)==0x80)
    {
    t1=Dword(temp1);
    MakeCode(t1);
        Wait();
    temp1=temp1+4;
    }
        }
if (t==1){MakeCode(temp1);}
t=0;
temp1=temp1+4;
}


}


static isPrint(c)
{
   return ((c >= ' ' && c < 0x7F) || c == 0x0a || c == 0x09);
}

static MakeStrings(StartAddr,EndAddr)
{
   auto ea, endea, startea;

   Message("Searching for strings...\n");
   SetLongPrm(INF_STRTYPE, ASCSTR_TERMCHR);

   ea = EndAddr;  //MinEA();;
   endea = MaxEA();;
   while (ea < endea && ea != BADADDR) {
      ea = FindUnexplored(ea, SEARCH_DOWN);

      // data aligned on 32bit boundary
      if ((ea & 3) == 0) {
         if (isPrint(Byte(ea))) {
            startea = ea;
            while (ea != BADADDR && isPrint(Byte(ea)))
               ea++;
            if (Byte(ea) == 0x0 && ea - startea > 3)
               MakeStr(startea, ea + 1);
         }
      }
   }

   Message("Finished searching for strings.\n");
}

And here are some routines that I labled in the 68c4 part of IDA disassembly:

80400000 base addr

8047E2CC  # serial send
80404B30  # send early init messges
8040990C  # file length test and md5
80409B24  # ip download and file test call
80409D04  # test flag for need to update
80404908  # Press Ctrl+C to stop auto-boot...
804043D8  # init
80401A5C  # test RAM and call to boot
80401B74  # RAM OK so "boot"
8047BD7C  # mem compare
8047BDBC  # memcopy?
8040CCFC  # get CC 96 28 EE.. md5 hash/key? addr
80405B34  # compute md5?

8047C02C  # find NULL end?
80405BD4  # md5 init?
80409524  # Socket create/TFTP ready test/download
80409DFC  # write to flash?
8041855C  # show progress with **** chars
80418750  # call show progress routine
804188F0  # Flash addr lookup
--------------------------------------------------------------------
And a part of the disassembly around where I look more carefully:

ROM:80409978
ROM:80409978 loc_80409978:                            # CODE XREF: sub_8040990C+44j
ROM:80409978                 addiu   $v1, $fp, 0x48+var_30
ROM:8040997C                 lw      $v0, 0x48+arg_0($fp)
ROM:80409980                 addiu   $v0, 4           # point to file start+4 bytes
ROM:80409984                 move    $a0, $v1         # dest
ROM:80409988                 move    $a1, $v0         # source
ROM:8040998C                 li      $a2, 0x10        # number
ROM:80409990                 jal     sub_8047BDBC     # memcopy?
ROM:80409994                 nop
ROM:80409998                 jal     sub_8040CCFC     # get CC 96 28 EE.. md5 hash/key? addr
ROM:8040999C                 nop
ROM:804099A0                 sw      $v0, 0x48+var_38($fp)
ROM:804099A4                 lw      $v0, 0x48+arg_0($fp)
ROM:804099A8                 addiu   $v0, 4
ROM:804099AC                 move    $a0, $v0         # dest
ROM:804099B0                 lw      $a1, 0x48+var_38($fp)
ROM:804099B4                 li      $a2, 0x10        # overwrite the current md5 with stock string
ROM:804099B8                 jal     sub_8047BDBC     # memcopy?
ROM:804099BC                 nop
ROM:804099C0                 addiu   $v0, $fp, 0x48+var_20
ROM:804099C4                 lw      $a0, 0x48+arg_0($fp)  # point at start of file
ROM:804099C8                 lw      $a1, 0x48+arg_4($fp)  # file length
ROM:804099CC                 move    $a2, $v0         # where to save result
ROM:804099D0                 li      $a3, 5
ROM:804099D4                 jal     sub_80405B34     # compute md5?
ROM:804099D8                 nop
ROM:804099DC                 addiu   $v0, $fp, 0x48+var_30
ROM:804099E0                 addiu   $v1, $fp, 0x48+var_20
ROM:804099E4                 move    $a0, $v0
ROM:804099E8                 move    $a1, $v1
ROM:804099EC                 li      $a2, 0x10
ROM:804099F0                 jal     sub_8047BD7C     # mem compare
ROM:804099F4                 nop
ROM:804099F8                 beqz    $v0, loc_80409A1C
ROM:804099FC                 nop
ROM:80409A00                 la      $a0, aMd5ChecksumIsN  # "md5 checksum is not correct!\n\r"
ROM:80409A08                 jal     sub_8047E2CC     # serial send
ROM:80409A0C                 nop
ROM:80409A10                 li      $v0, 0x4655
ROM:80409A14                 j       loc_80409B0C
ROM:80409A18                 nop

jvvh5897 wrote:

And here are some routines that I labled in the 68c4 part of IDA disassembly:

Hi, jvvh
Your script and analysis are really helpful.
But I have a doubt that need your help.
How do you know we should load the code into 0x80400000 rather than other addresses?
Thank you agian.

Well, that is a hard question in general. Specifically, I look at the code first and find clues--I look in the header and see if something tells the code where to put the un-packed stuff, I try a disassemble and look at what I get to see what I can figure out from it (there often is a pair of li commands for $a0 and $a1 registers where one of the two is the ending address of the file in RAM and I can just subtract the file size to end up with the start address). If nothing else I look for the calls to routines to actually point to the start of a routine--with MIPS code the calls are absolute addressed. Or I look for pointers to string to point to the start of strings and argue from them to file start.

There are a couple of general things you can count on. The flash address base is likely to be something like 0xbfc00000 or 0x8fc00000 for 4 meg flash. The start of RAM is likely to be 0x80000000 or 0xa0000000. So you can look for areas in the code that use addresses like the above and figure some of what you need from that.

Reverse engineering code is guess work. You look for other info to help you like datasheets for chips, example source code for similar processors can be a big help (did you know that there are MIPS core processors in FTA reciever boxes), and look for tools that have been generated--gcc can compile MIPS code, there are disassemblers for MIPS (I've compiled some source code for a simple MIPS disassembler that was fun to play with), there are simulators for MIPS. Anything can help you figure out how to reverse engineer--the more you know the easy it is likely to be.

jvvh5897 wrote:

Anything can help you figure out how to reverse engineer--the more you know the easy it is likely to be.

Get it.
Thanks you very much.

BTW, the base address for the mainsw is 0x80001000 after lzma extraction. If you look in a disassembly, you will find a li instruction to load the $sp with 80000ff0 and one to load the $gp with something close to the file length in RAM. I knew that the stack pointer builds downward to the base for the code had to be past the $sp value. And the $gp tends to have a little of the end of file within the range of $gp - 0x8000. When I tried 0x80001000 as the lading addr in IDA, I got quite a bit of the code to disassemble and the calls to subroutines looked good and the pointers to strings looked good. I found the first strngs that I could and searched backward for the last 27 bd sequence and used that as my end addr in the IDC. Good results.

jvvh5897 wrote:

When I tried 0x80001000 as the lading addr in IDA, I got quite a bit of the code to disassemble and the calls to subroutines looked good and the pointers to strings looked good.

Good work.

Hi Folks,

i have bought chinesse version of 702N about year ago. I have tried to change header in EN FW, but without success cause of checksum.
If I have understood it corectly you have managed to get EN menu into CN firmware, right? I have read the complete topic, but it is simply to much for me, I am no programmer :-(.

Could you upload your modified FW somewhere? I would really appreciate it.
thank you in advance

One more question. If you want to upgrade new FW, you must take new cn version and do it again?

(Last edited by UFO-nec on 24 Jul 2013, 12:25)

I gave up on putting english menu into the ch fw. Instead I just modded the english fw at two places to let the box think it was ch fw and fixed the checksum. If you wanted to mod more than one english fw to use in the box then that would have to be done again, but no need to go back and forth between ch and eng fw unless you wanted to. The mods to eng fw are small and not worth posting a file IMO--anyone can do it.

thx for reply. Yes, sure. Anyone can do it. It is just matter of time.
But I still ask you, could you pls upload it somewhere and provide me a link (via PM if you dont wanna post it here)?

UFO-nec wrote:

But I still ask you, could you pls upload it somewhere and provide me a link (via PM if you dont wanna post it here)?

Hi, I haven't test it because I don't have a wr702n.
Try it at your own risk:
http://www.mediafire.com/download/za7z3 … -en-up.bin

(Last edited by lofrank on 25 Jul 2013, 03:41)

thx, downloaded, but can not try it now.
It seems that my router is bricked. I tried to flash newer chinesse FW yesterday, I have put new FW via tftp and waited few minutes befor restart, but something went wrong.  I can connect to router via WiFi, ip scanner find it on ethernet on 192.168.1.253 , but i can not access config.

I must try something like this:
http://forums.openpilot.org/blog/52/ent … mentsStart

If you can find the box with what you say you can it is not bricked. Odds are that your addr to get to the web pages is not the same. It changes when you put in the english sw too. Try 1.1 as the last two digits of IP addr. Use default password/user.

thx for trying to help, but it doesnt make any sense. I found the router on .1.253, I can ping it there, so how can it be on 1.1?
Of course that I tried it anyway, without success.

what about pressing the reset button? does it still pings on 1.253?

yep, sure. It was the first thing i have tried.

lofrank wrote:
UFO-nec wrote:

But I still ask you, could you pls upload it somewhere and provide me a link (via PM if you dont wanna post it here)?

Hi, I haven't test it because I don't have a wr702n.
Try it at your own risk:
http://www.mediafire.com/download/za7z3 … -en-up.bin

Flashed my WR702n with this firmware. Working as it should be. Thanks for posting!

Hey guys, looks like you have all made some headway with this guy!

I recently purchased the same device, not knowing it was a CH! However I have little to no idea about what you guys are doing with modifying the firmware update tongue

I have downloaded the link from lofrank, however for me it doesn't seem to update the device? It doesn't look like it's failing either - but the logs don't really show anything at all.

Is there any chance someone might be able to modify the current EN image to thinking it's CH for me?
- http://www.tp-link.com/resources/softwa … 130528.zip

Thanks for anyone who assists big_smile

you can try to install the dd-wrt firmware

RuntimeError wrote:
lofrank wrote:
UFO-nec wrote:

But I still ask you, could you pls upload it somewhere and provide me a link (via PM if you dont wanna post it here)?

Hi, I haven't test it because I don't have a wr702n.
Try it at your own risk:
http://www.mediafire.com/download/za7z3 … -en-up.bin

Flashed my WR702n with this firmware. Working as it should be. Thanks for posting!

Same here, flashed my chinese WR702n and now it's in fully English, god bless you!

damian wrote:

Hey guys, looks like you have all made some headway with this guy!

I recently purchased the same device, not knowing it was a CH! However I have little to no idea about what you guys are doing with modifying the firmware update tongue

I have downloaded the link from lofrank, however for me it doesn't seem to update the device? It doesn't look like it's failing either - but the logs don't really show anything at all.

Is there any chance someone might be able to modify the current EN image to thinking it's CH for me?
- http://www.tp-link.com/resources/softwa … 130528.zip

Thanks for anyone who assists big_smile

The file lofrank posted above is the modified version of this one you want.

From the status page of my wr702n flashed with it:

Status

Firmware Version:
4.19.1 Build 130528 Rel.52704n 

Hardware Version:
WR702N 1.0 00000000

Hi, I have downloaded lofrank file but have no clue to setting up tftp to flash my WR702n. I am using Tftpd32.exe with the Current Directory set to the proper file location. When I try to upgrade I get (translated):
Error Code: 18000
Upgrade is not successful, check if you upload a file on a TFTP server, and whether the appropriate directory.

I have never used tftp before and obviously missing something. Any help is appreciated but a step by step guide would be wonderful.

pmhoppe wrote:

Hi, I have downloaded lofrank file but have no clue to setting up tftp to flash my WR702n. I am using Tftpd32.exe with the Current Directory set to the proper file location. When I try to upgrade I get (translated):
Error Code: 18000
Upgrade is not successful, check if you upload a file on a TFTP server, and whether the appropriate directory.

I have never used tftp before and obviously missing something. Any help is appreciated but a step by step guide would be wonderful.

Have you run it as Administrator?

pmhoppe wrote:

Hi, I have downloaded lofrank file but have no clue to setting up tftp to flash my WR702n. I am using Tftpd32.exe with the Current Directory set to the proper file location. When I try to upgrade I get (translated):
Error Code: 18000
Upgrade is not successful, check if you upload a file on a TFTP server, and whether the appropriate directory.

I have never used tftp before and obviously missing something. Any help is appreciated but a step by step guide would be wonderful.

You need to manually set your PC's IP address to something like 192.168.1.100 , netmask to 255.255.255.0 and plug the router into you PC's ethernet port with RJ45 cable.

Run Tftpd32.exe as admin (RIGHT CLICK, select RUN AS ADMINISTRATOR).
In Tftpd32.exe click on the SETTINGS button at bottom of window, and change the BASE DIRECTORY to the directory where you have saved the wr702nv1-en-up.bin file.

Connect to the router via your web browser using 192.168.1.253 as the URL address. Then in the update menu for the firmware, put the wr702nv1-en-up.bin and the ip address of the PC you are running Tftpd32.exe on (eg 192.168.1.100) and it should work. When its gotten to 100% when downloading new firmware onto router, just leave it for 5 mins to make sure everything is completed, and then reboot router (unplug from power and replug in).

It should now be updated to english version. The routers IP address will now be 192.168.0.254, or if you want to connect wirelessly the security key is the last 8 characters of the routers MAC - found on bottom of router.