自己刷了个qca9563用作ap玩,奈何GPIO定义不清楚,wan口灯什么的都不知道引脚定义。
某快的GPIO定义网上只有寥寥言语,在某鱼商家眼里,这些都是能卖钱的机密信息。
于是想既然有固件了,我为何不从固件里面寻找信息呢?
开始百度搜索了相关内容,找到两篇有帮助的:
手工使用二进制工具修改H大的breed的gpio复位键的心得-续-逆向恢复符号表
于是按照流程开始研究,首先是在KALI里面用binwalk解包固件得到名为60040的内核
开始导入IDA PRO里面进行逆向,确实一个函数都没有。
然后用rbasefind爆破基地址,16线程跑了一个晚上,然后告诉我基地址是0x80060000?
我早该想到的。一半路由器内核加载地址都是这个。 (这里有个坑,rbasefind默认为小端,这里要加 “-b”)
修改基地址后,按c试下,大部分函数都能出来了,但是字符串什么的都还是不显示,上面文章说ghirda能够识别更多的函数和字符串,于是换用ghirda,感觉确实分析功能更强大。
找了找和led有关的字符串和函数,发现了几个疑似的,但是并不像原文章那样清晰明了,直接函数里面把参数和代入的变量都显示出来,毕竟固件不一样嘛。
然后想办法按照文章所述恢复符号表,研究了半天发现固件不一样,符号表细节处也不一样,
在fjh1997所用的固件中,符号表定义如下:
但是在爱快的固件里面,有三千多个函数名称,但是都是对应的连续的80开头的,并没有偏移量,这可怎么对应?
事情陷入了僵局,纠结了两三天,各种写脚本测试,仍是无功而返,我相信是有办法对应函数名称的,但是不得其法。
无意中翻看,发现有一部分地址不是连续的,后面跟的有数据,但是和原文中的数据不一样,也是没有偏移地址。但是好在里面有数据了,开始考虑这个地址后面的数据是什么意思。
前面0x802f91dc搜了下,是个字符串alfa:red:led_5,或许是变量,那后面的0xc和0x80是什么意思,也是偏移么?事实证明是我想多了,测试了一大圈,最后发现0xc直接就是变量赋值,结果明明就在眼前啊!!!
于是找了几个眼熟的引脚名称,拿去和老版的openwrt源代码里面的引脚定义对比下,完美契合!
虽然没有找到恢复函数名称的方法,但是能找到变量定义,尤其是引脚定义也是可以啊!!!
于是按照思路写了IDA脚本,是python2脚本,没有int.from_bytes()函数,不够优雅。
tag_start=0x80383fd8
tag_end=0x80387150
def get_str(addr, l):
temp = ''
for i in range(0, l):
temp = temp + ''.join('%02x' % ord(c) for c in get_bytes(addr+i,1))
return temp
while True:
if get_str(tag_start, 1) == '80':
var_addr = int(get_str(tag_start, 4),16)
var_name = get_strlit_contents(var_addr)
if var_name != None:
var_val = get_str(tag_start+11, 1)
tag_start = tag_start + 0x10
print var_name + ' ' + str(int(var_val,16))
else:
tag_start = find_binary(tag_start+1,SEARCH_DOWN, '80')
elif get_str(tag_start, 1) == '00':
var_addr = int(get_str(tag_start+12, 4),16)
var_name = get_strlit_contents(var_addr)
if var_name != None:
var_val = get_str(tag_start+7, 1)
tag_start = tag_start + 0x24
print var_name + ' ' + str(int(var_val,16))
else:
tag_start = find_binary(tag_start+1,SEARCH_DOWN, '80')
else:
tag_start = find_binary(tag_start,SEARCH_DOWN, '80')
print tag_start
if tag_start >= tag_end:
break
写的不是很完美,因为start到end地址里面类似结构体的变量和数据组长度不一致,有些意义未明,排除了一些干扰,只找 led 和 button 的数据结构。因为这两种长度信息比较固定和统一。
led_gpio
80 2F A7 68 00 00 00 00 00 00 00 02 80 00 00 00
80 2F A7 80 00 00 00 00 00 00 00 01 80 00 00 00
80 2F A7 98 00 00 00 00 00 00 00 04 80 00 00 00
80 2F A7 AC 00 00 00 00 00 00 00 00 80 00 00 00
80 2F A7 C0 00 00 00 00 00 00 00 06 80 00 00 00
button_gpio
00 00 01 98 00 00 00 08 00 00 00 01 80 2F 92 74 00 00 00 01 00 00 00 00 00 00 00 3C 00 00 00 00 00 00 00 00
00 00 02 11 00 00 00 03 00 00 00 01 80 2F A7 BC 00 00 00 01 00 00 00 00 00 00 00 3C 00 00 00 00 00 00 00 00
00 00 01 02 00 00 00 0B 00 00 00 01 80 2F 9E 40 00 00 00 01 00 00 00 00 00 00 00 3C 00 00 00 00 00 00 00 00
运行,bingo,拿到的结果找几个熟知的型号路由器源代码引脚定义 对比下,完全一致,目的达到了。
我相信里面可以挖掘的东西还有很多,函数名称怎么对应,后续有带研究。希望研究有结果的可以告知。
后续修改我没有测试,按理说修改GPIO对应值之后,将内核重新打包,应该是可以达到目的的。