您的位置:首页 > 编程语言 > C语言/C++

[C/C++标准库]_[初级]_[查找内存数据中的指定值]

2014-01-20 00:11 375 查看

memchr()

bsearch()

memmen()

场景:

1. 如需要修改一个二进制文件的数据,需要先把需要修改的数据转换为16进制,查找到偏移量后修改.

2.这里介绍下开发工具Sublime Text2,确实是一个好ide,可以用gdb,查看和修改文件的16进制内容等,免费使用,收费能去掉弹出提示.我觉得已经可以完全替代editplus了,因为它是支持插件开发的,插件可以用python开发.这个优势不是editplus能比的.前面说的gdb和16进制查看修改都是插件。改天把eclipse也替换掉,eclipse反映总是跟不上我的速度,好麻烦。估计是本本配置不好的原因.4G内存,2.3G cpu双核都搞不定eclipse啊~~~

。之前写简单代码都用的crack版editplus,这对支持正版的我来说不是长久之际。sublime
text2免费使用,扩展容易,学习容易。比gvim和emacs容易多了!!!!强烈推荐还没找到好的轻量级ide的可以用sublime text2。用了它之后绝对想多写代码。哈哈。

代码:

/*
** 1.查找内存值,也可用于查找字符串.
**   一般用于读取和修改二进制内存数据.
*/

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <algorithm>

void TestMemChr()
{
//1.memchr,search single int data.
//超找不到,就返回NULL.
//查找单个整型数据,可以出现0x0
unsigned char chr_char[8] =
{0x21,0x69,0x6E,0x63,0x00,0x22,0x6E,0x69};
void *res = memchr(chr_char,0x6E630022,8);
assert(res);
//可以修改这部分内存
//printf("chr_char[2]: %x\n",*((unsigned char*)res));
//printf("chr_char[2]: %x\n",*((unsigned char*)(res+1)));

*((unsigned char*)res) = 0xff;
printf("chr_char[5]: %x\n",chr_char[5]);
assert(chr_char[5] == 0xff);

//单个字符
res = memchr(chr_char,'i',8);
assert(res);
assert(*((unsigned char*)res) == 'i');
printf("res: %x\n",*((unsigned char*)res));

//4字节的字符串,32位下
char in[] = {'i','n',0,0};
res = memchr(chr_char,*((int*)in),8);
assert(res);
assert(*((unsigned char*)res) == 'i');
assert(*(((unsigned char*)res)+1) == 'n');
assert(*(((unsigned char*)res)+2) == 0x63);
printf("*(((unsigned char*)res)+2): %x\n",*(((unsigned char*)res)+2));
}

static int compareBSearch(const void* a,const void* b)
{
return ( *(unsigned char*)a - *(unsigned char*)b );
}

void TestBSearch()
{
unsigned char chr_char[] =
{0x21,0x69,0x6E,0x63,0x00,0x22,0x6E,0x69};
//2.bsearch,搜索二进制数据,不限字节数.但是需要降序排列。
//只适用于查找一个类型数据在数组里是否存在和位置偏移量.
//查找的key必须和数组里的类型大小一致.
//参考: http://www.cplusplus.com/reference/cstdlib/bsearch/ unsigned char i = 0x69;
printf("sizeof(unsigned char): %d\n",sizeof(unsigned char));
//注意:一定要先qsort,不然绝大多数都会失败.
qsort(chr_char,8,sizeof(unsigned char),compareBSearch);
void* res = bsearch(&i,chr_char,8,sizeof(unsigned char),compareBSearch);
assert(res);
printf("res: %x\n",*((unsigned char*)res));
}

void* _memmem(const void *l, size_t l_len, const void *s, size_t s_len)
{
register char *cur, *last;
const char *cl = (const char *)l;
const char *cs = (const char *)s;

/* we need something to compare */
if (l_len == 0 || s_len == 0)
return NULL;

/* "s" must be smaller or equal to "l" */
if (l_len < s_len)
return NULL;

/* special case where s_len == 1 */
if (s_len == 1)
return memchr(l, (int)*cs, l_len);

/* the last position where its possible to find "s" in "l" */
last = (char *)cl + l_len - s_len;

//cur[0] == cs[0] 这里是为了减少memcmp的调用次数,先比较首字节.
for (cur = (char *)cl; cur <= last; cur++)
if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
return cur;

return NULL;
}

void TestMemMem()
{
//4.逐个匹配.
unsigned char l_char[] =
{0x21,0x69,0x6E,0x63,0x00,0x22,0x6E,0x67};
//这里设定了超过32位测试.
unsigned char s_char[] =
{0x6E,0x63,0x00,0x22,0x6E};
//1.由于memmem并不是标准库里的,所以copy了csdn bbs里介绍的freebsd里的参考.
//先感谢 mymtom
//http://bbs.csdn.net/topics/390333234
void* res = _memmem(l_char,8,s_char,5);
assert(res);
assert(*(((unsigned char*) res)+5) == 0x67);
printf("*(((unsigned char*) res)+5): %x\n",*(((unsigned char*) res)+5));
}

void TestCustomizeClassIterator()
{
//暂时未实现

}

void TestKmp()
{
//暂时未实现
}

void TestBm()
{
//暂时未实现
}

int main(int argc, char const *argv[])
{
TestMemChr();
TestBSearch();
TestMemMem();
TestCustomizeClassIterator();
TestKmp();
TestBm();

return 0;
}


今天转去用Sublime Text2开发了,写了那么久代码只占用了30m,换做eclipse写了2小时左右应该就300-400m内存占用了.

配上精美Sublime Text2截图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: