Loading... 看了一段时间,暂时还没有找出洞,自己还是太菜了,考虑到题目的逻辑较复杂,结构体也较多,在这里先记录一下,免得到时候忘了。 程序总共有 7 个功能,在 main 函数中使用一个 switch 来跳转,简单重命名一下如下 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/844816208.png "></div> ### recipe 这个函数又有三个功能 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/3962888461.png "></div> #### add_recipe 重命名一下如下 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/3601842535.png "></div> 这里面涉及到 recipe 的单向链表结构体,我猜测其结构如下 ```cpp struct RECIPE_LIST { char recipe_name[24]; struct INGREDIENT *Ingredient[13]; struct RECIPE_LIST *next; }; ``` 其中的 `struct INGREDIENT` 我猜测其结构为 ```cpp struct INGREDIENT { char name[32]; int price; int ingredient_left; }; ``` 也就是每一个 recipe 结构体维护其自己的名字和该菜需要使用的食材(ingredient)。而每个 INGREDIENT 结构体则维护自己的名字、价格和所剩的数量。 recipe 链表的头指针处于偏移 0x2050D0 处,IDA 分析时发现这个指针是通过处于偏移 0x2050C8 的基址寻址的,而此处又是 recipe_info 的地址,所以把二者合成一个结构体 ```cpp struct LIST_HEAD { struct Recipe_Info *recipe_info; // 上面命名不是很合适,我后来改成了 struct ALL_INGREDIENT *all_ingredient struct RECIPE_LIST **recipe_list_head; }; ``` 这里的 Recipe_Info 结构体(后来改名为 ALL_INGREDIENT)结构我猜测为 ```cpp struct Recipe_Info // 修改为 ALL_INGREDIENT { struct INGREDIENT *ingredient[10]; }; ``` LIST_HEAD 中的 recipe_info(改名为 all_ingredient)维护当前所有的食材和其个数。 说回到函数本身,这是添加食谱(recipe)的函数,我们可以自定义其食材,然后会被链接到食谱链表的尾部。似乎并没有什么洞。 #### remove_recipe <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/1010995755.png "></div> 这里就是根据菜谱的名字来解链特定的菜谱,然后通过 realloc 来对要被删除的食谱进行 free。 #### show_recipe <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/14613948.png "></div> 这里可以打出所有菜谱的名称和其食材的名称,如果可以做到在链表中保留一个被 free 过的 chunk 的话就有可能通过该函数实现 leak。 ### Assignment <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/227333245.png "></div> 这个函数主要做的就是给 NPC 吃东西,NPC 会从食谱中随便选一个食物然后要求我们给他吃,如果我们有对应的食物且选择可以提供,那么就可以给 NPC 吃,且可以增加自己的经验(经验到 100 后就会升级),然后增加级别。最后食物会从食物链表中解链,并通过 realloc 进行 free。 这里的食物链表结构我猜测如下 ```cpp struct FOOD_LIST { char name[24]; unsigned int price; int dummy1; __int64 energy; struct FOOD_LIST *next; struct FOOD_LIST *prev; }; ``` 每一个食物维护自己的名字、价格和能量(能量在后面的 eat 功能中有用),并且通过 next 和 prev 指针维护双向链表。 好像也没有明显的漏洞 ### show_chief_info <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/2031171667.png "></div> 函数很简单,就是输出厨师的信息,可见一个厨师有三个维度的数值 * level:一些对食材的操作对 level 有要求 * power:做食物(do_cooking)需要消耗 power,可以通过 eat 来补充 * money:买食材需要花钱,通过给 NPC 做饭(Assignment)或卖出食物(sell_food)可以获得钱财 ### do_shopping <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/3681398449.png "></div> 这个功能里面也有三个子功能,主要是对食材和食物的操作,可以卖出、购买和制作。 #### sell_food <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/2116536921.png "></div> 卖出指定食物,获得其 price 的钱,然后解链并 free,好像没什么漏洞 #### buy_ingredint <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/858456494.png "></div> 购买指定个数个食材,每个食材的个数是由位于偏移 0x205080 处的指针来维护的。 #### make_food <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/2620528855.png "></div> 这个函数让我们制作自己的食材(命名有些不恰当,但是我懒得重传图片了,您知晓就行了),每次制作食材都需要花费 100 块钱。 ### do_cooking 函数比较长,分两段传。 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/2517129919.png "></div> <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/138789661.png "></div> 这里就是根据菜谱制作食物,看起来很长但是好像还真没有什么洞.. 到这里就功能就分析完了,无奈的确没有发现什么洞,希望明天可以找到洞 PWN 了。 最后修改:2021 年 06 月 15 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧