不常用的ini操作方法

六月 17th, 2010 by shyandsy
2

(   1   )使用得  最  频繁  的是   GetPrivateProfileString   和   WritePrivateProfileString  ,  没有   WriteProfileInt\WritePrivateProfileInt   函数[han shu]。

(   2   )   Get   系列读取[du qu]节键值,如果文件[wen jian]路径[lu jing]有误或节键名不对则返回设定的默认[mo ren]值。

(   3   )访存自定义配置[pei zhi]  文件[wen jian]时,文件[wen jian]路径[lu jing] lpFileName 必须完整 , 文件[wen jian]名[wen jian ming]前面的各级目录必须存在。如果 lpFileName 文件[wen jian]路径[lu jing]不存在,则函数[han shu]返回 FALSE ,  GetLastError =   ERROR_PATH_NOT_FOUND  。  如果路径[lu jing]正确,但是文件[wen jian]不存在,  则该函数[han shu]将先创建该文件[wen jian]。如果路径[lu jing]及文件[wen jian]存在,则在现有 ini 文件[wen jian]基础上进行读写[du xie]。

如果   lpFileName   只  指定文件[wen jian]  名而  没有路径[lu jing]的话,  调用[tiao yong] API 将  会去   Windows   的安装[an zhuang]目录去  查找[cha zhao]  而不会在当前目录[dang qian mu lu]  查  找  。

( 4 )要对调用[tiao yong] API 的模块[mo kuai] (exe) 所在目录下进行配置[pei zhi]文件[wen jian][pei zhi wen jian]操作,可使用形如“ .\config.ini ”的相对路径[lu jing]。

( 5 )调用[tiao yong]  WritePrivateProfileSection  ,若参数[can shu]三     lpString     为   NULL  ,则可将对应 section 的全部内容清空;调用[tiao yong]  WritePrivateProfile  String  ,若参数[can shu]三     lpString     为   NULL  ,则可将对应 key 删除[shan chu]。

Posted in vc++

UNICODE串转换成char类型串的四种方法

六月 13th, 2010 by shyandsy
0

1. 调用 WideCharToMultiByte() API

int WideCharToMultiByte (
    UINT    CodePage,                //1 Unicode编码的字符页,Unicode编码有字符页的概念,比如gb2312/936,big5/950等
    DWORD   dwFlags,                //2 如何处理复合unicode字符,详细查google
    LPCWSTR lpWideCharStr,        //3 待转换的unicode串
    int     cchWideChar,                //4 表示参数3的长度  传递-1表示以0×00结尾
    LPSTR   lpMultiByteStr,            //5 接受转换后的串的字符缓冲
    int     cbMultiByte,                    //6 表示参数5lpMutiByteStr的字节大小 通常sizeof一下
    LPCSTR  lpDefaultChar,        //7 NULL 具体google
    LPBOOL  lpUsedDefaultChar//8 NULL 具体google
);

2. 调用CRT函数wcstombs()

size_t wcstombs (
    char*          mbstr,
    const wchar_t* wcstr,
    size_t         count );

3. 使用CString构造器或赋值操作

// 假设有一个Unicode串wszSomeString

CString str1 ( wszSomeString ); // 用构造器转换
CString str2;

str2 = wszSomeString; // 用赋值操作转换

4. 使用ATL串转换宏

#include <atlconv.h>

// 还是假设有一个Unicode串wszSomeString

{
    char szANSIString [MAX_PATH];
    USES_CONVERSION; // 声明这个宏要使用的局部变量

    lstrcpy ( szANSIString, OLE2A(wszSomeString) );
}
Posted in vc++

Visual Stdio 2008出现mfc90d.dll错误

六月 13th, 2010 by shyandsy
1
VS 2005/VS 2008在生成可执行文件时使用了一种新的技术,该技术生成的可执行文件会伴随生成一个清单文件(manifest file)(.manifest后缀文件)(其本质上是XML文档,你可以用文本编辑器打开看看),并在链接完成后将该清单文件嵌入到exe文件中(默认情况下)。而在FAT32文件系统中,在处理清单文件阶段,当增量链接时不能完成清单文件的更新(默认情况下),于是造成清单文件嵌入失败,从而使该exe文件运行时没有相应的清单文件而运行失败并提示如上错误。

解决方案很多,列举如下:

1. 由于这是在链接动态运行库出现的问题,所以你可以选择代码生成的连接方式为 /MTd 而非 /MDd ,不用这些DLL文件从而避免问题的出现。该方法有一个很显然的缺点:适用范围有限,不推荐该方法。

注:/MT /MTD MD /MDD 之间的关系可以参见 VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结;另外如果使用/MT 或者/MTD 那么生成的文件的尺寸基本上是使用/MD 或者/MDD的10倍大小

2. 既然跟FAT32系统有关,那么我们可以选择在NTFS文件系统中开发从而避免该问题,此方法同上,也是采用的回避问题的方式,不提倡。(我个人推荐使用这种方法)

3. 该方法仍与FAT32有关:在项目的“属性|配置属性|清单工具|常规(Project | Game Properties | Configuration Properties | C/C++ | Code Generation | Runtime Library)”中的“使用FAT32解决办法”选择“是”(默认为“否”),重新生成项目即可解决问题。该方法是唯一真正针对问题所在而提出的解决方法,使清单工具可以正确更新。(此方法是官方解决方法,也比较方便,推荐)

4. 既然问题是在更新嵌入的清单文件时发生的,由于FAT32的原因而未能更新嵌入的清单文件,于是我们有如下两种解决方法:

(1)不启用增量链接。在项目的“属性|配置属性|链接器|常规”中的“启用增量链接”选择“否”。此方法阻断了问题产生的源头,其每次生成exe文件时都直接嵌入清单文件,而不是默认的根据时戳而决定是否更新清单文件。

(2)不嵌入清单文件。在项目的“属性|配置属性|清单工具|输入和输出”中的“嵌入清单”选择“否”,从而在生成exe文件时附随生成一个清单文件(默认情况下,其文件名为exe文件的全名加上“.manifest”),避免了嵌入清单文件可能失败的问题。在程序运行时,会用到该清单文件。显然,这种方式使可执行程序产生了更多的外部依赖,不推荐。

另外,还有一个不能称为方法的土办法:每次Build前手动删除*.ilk文件(增量链接文件)(当然可以在项目属性中写入删除命令,使其自动执行),不推荐该土办法。

最后,总结一下:

1. 此问题只在特定条件下才会出现:在FAT32文件系统中编译、默认设置(增量模式、不启用FAT32解决方案、嵌入清单文件)、非第一次生成可执行文件文件(即在增量连接、更新清单文件时)。(注意)

2. 解决方案1和4.1方便实用,推荐使用。

ps:我个人认为解决这个问题的最好方法就是使用vc2005/vc2008的时候,在ntfs文件系统上进行开发(也就是第2种方法)。当前的绝大多数软件在ntfs文件系统都能够正常的运行(即便是dos类的工具也能在ntfs文件系统上良好的运行),为什么还要死抱着fat/fat32文件系统不放呢?

另外要注意一个概念问题,“VC2008下提示找不到MSVCP90D.dll”这是属于开发问题,是由于windows文件系统的bug(fat32的bug),导致vc2005/vc2008开发工具编译出来的程序不能正常的运行。

Posted in vc++

BSTR、char*和CString转换

四月 27th, 2010 by shyandsy
6

BSTR、char*和CString转换
(1) char*转换成CString
  若将char*转换成CString,除了直接赋值外,还可使用CString::Format进行。例如:
view plaincopy to clipboardprint?
char chArray[] = "This is a test";
char * p = "This is a test";
char chArray[] = "This is a test";
char * p = "This is a test";  

  或

 Read the rest of this entry »

Posted in vc++

[转]CGridCtrl帮助中文版

四月 27th, 2010 by shyandsy
1

GridCtrl学习指南

当我努力为显示和编辑现有表中的数据而使用 CListCtrl 到了极限之后,我意识到我所需要的只不过是一个专用的

Grid控件而已。于是我开始着手写自己的Grid控件,但为了节省时间我决定修改Joe Willcoxson’s的免费控件 WorldCom,

你可以在以下站点 http://users.aol.com/chinajoe/wcmfclib.html 找到这个东东。为了让它能做我要做的事情,我

分解了他的代码,并且重新修改。由于代码经过太多的修改,我甚至不能确信最终是否还存在最初的代码。但无论如何,

Joe的代码是一个大框架,而我只是在上面进行加工而已。

工程一开始的时候是计划尽可能的简单但是当我不断发现我不得不考虑新特色的时候,它迅速的膨胀成为一个梦魇。虽然

测试并不是没有遗漏–但是我还是坚信情形不会变得太坏J。Joe很善意的允许我开放这个资源而不附加任何的语句(毕竟

那是基于他的代码),但是由于工程象马拉松似的,所以我在这段代码中使用了两个非常不成熟的条件: Read the rest of this entry »

Posted in vc++

FS寄存器,关于前一篇中获得当前PEB的一些疑点

十二月 17th, 2009 by shyandsy
4

FS寄存器指向当前活动线程的TEB结构(线程结构)

偏移 说明
000 指向SEH链指针
004 线程堆栈顶部
008 线程堆栈底部
00C SubSystemTib
010 FiberData
014 ArbitraryUserPointer
018 FS段寄存器在内存中的镜像地址
020 进程PID
024 线程ID
02C 指向线程局部存储指针
030 PEB结构地址(进程结构)
034 上个错误号

得到KERNEL32.DLL基址的方法


Read the rest of this entry »

Posted in 汇编与逆向

kernel32里的 GetVersion 函数的逆向分析

十二月 14th, 2009 by shyandsy
4

今天在家调试程序,跟进了一个函数kernel32里面的GetVersion函数。最近刚好在学逆向。心一横,干脆把它逆了。

代码如下:

0043846A  |.  FF15 70F14500 call    dword ptr [<&KERNEL32.GetVersion>]                ;  kernel32.GetVersion

7C81126A >  64:A1 18000000       mov     eax, dword ptr fs:[18]         ; 获得当前线程的TEB地址
7C811270    8B48 30                       mov     ecx, dword ptr [eax+30]        ; 在TEB偏移30h处获得PEB地址
7C811273    8B81 B0000000        mov     eax, dword ptr [ecx+B0]
7C811279    0FB791 AC000000   movzx   edx, word ptr [ecx+AC]
7C811280    83F0 FE                       xor     eax, FFFFFFFE
7C811283    C1E0 0E                      shl     eax, 0E
7C811286    0BC2                            or      eax, edx
7C811288    C1E0 08                      shl     eax, 8
7C81128B    0B81 A8000000        or      eax, dword ptr [ecx+A8]
7C811291    C1E0 08         shl       eax, 8
7C811294    0B81 A4000000        or      eax, dword ptr [ecx+A4]
7C81129A    C3                                retn
解析:
Posted in 汇编与逆向

哈哈,阳光总在风雨后

十二月 13th, 2009 by shyandsy
0

呵呵,生活终归还是美好的。

虽然造物弄人,但只要坚持,一般结果都还是好的。

我也比较服我自己。

我们又在一起了。

搂着自己很爱的女孩是一种幸福。

 

Posted in 心路

【天书笔记】C函数传参过程

十二月 13th, 2009 by shyandsy
1

一.C函数调用与堆栈的关系

C语言通过堆栈将参数传入函数内部

push和pop的时候esp用于指向栈顶——栈顶总是栈中地址最小的位置。push则esp减少,pop则esp增加。

二.函数调用规则

定义:函数调用规则是指调用者和被调用函数之间传递参数及返回参数的方法。

Windows上常用的有Pascal方式,WINAPI(_stdcall)方式以及C方式(_cdecl)。

1._cdecl方式

参数入栈:参数从右到左依次入栈

清理方式:函数返回后,调用者负责清理堆栈。这种调用会生成较大的可执行程序。

2._stdcall方式(WINAPI方式)

参数入栈:参数从右到左依次入栈

清理方式:被调用函数在返回前自行清理堆栈。生成代码比_cdecl方式小。

3.Pascal方式

入栈方式:参数从左到右依次入栈

清理方式:被调用函数在返回前自行清理堆栈

不支持可变参数的函数调用

此外Windows内核中还有常见的_fastcall快速调用;c++中有_thiscall方式。

任何调用方式,最终返回值都是写入eax,然后返回。外部从eax中取得返回值。 Read the rest of this entry »

Posted in 汇编与逆向

或许我就不该这么做,我想骂人,但不想骂你

十二月 9th, 2009 by shyandsy
2

 /////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

我受不了了

杯具

一切都用C++注释的方式来表示吧

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

你走了,这里剩下我一人。

我要去外面疯一圈

/////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////

我就不该容许自己有爱情。。。。。。。。。

 

 

Posted in 心路
վ:Ħ Ϻgay ŰĦ Ϻ տ ɽ ɽ ŰĦ Ϻ˹˾ ŰĦ ϺŰĦ ˹˾ ݰĦ ŰĦ Ħ ϺĦ ͬ־ Ѽ˹˾ ŰĦ ϺѼ ɳ᳡ shenzhen massage ŰĦ ͬ־ Ϸʿյά ϲŰĦ 人˿ఴĦ ɽ˹˾ Ϻ Ѽ˿ Ħ ֣ŰĦ ˹˾ ݼѼ Ϻ ǿ Ϻ ڰ᳡۸ °˾