posts - 20,comments - 15,trackbacks - 0

VC to Object-C

本博客所有文章均为原创, 谢绝转载

1. Class
// 类声明
@interface MyTest : NSObject
{
// @private 私有, @package 
 int num1;
 int num2;
}

// 属性
@porperty int num1, num2;

// 类方法
-(void) print;
-(int) Test2;

// 多参数函数
// 方法称为setTo:set2:, 其实就是void setTo_set2(int a, int b);
// Object-C和C++比更象一种描述语言
// 调用[mytest setTo : 1 set2 : 3];
-(void) setTo : (int) a set2: (int) b
{
 num1 = a;
 num2 = b;
}

// 类似于vc里的static void print2();
// 调用[MyTest print2];  同CMyTest::print2();
+(void) print2;
@end

// 类实现
@implementation MyTest

// 编译器会自动生成类似get,put的方法
// 不用@porperty, 需要自己现实现属性数据的读写
@synthesize num1, num2;

-(void) print
{
 // 输出到调试区, 类似OutputString
 NSLog(@"%i/%i", num1, num2);
}

-(int) Test2
{
 return 10;
}
@end


// 调用
MyTest* p = [[MyTest alloc] init]; // init是NSObject的方法, 类似C++里的构造, 不过oc只能用指针
[p setTo : 1 set2 : 3];
[p print];
[p release];

// 输出
1/3


2. 带分类的类, 分类就是提供一个方法组合
//1. 分类不能建变量
//2. 最好不要重载主类的方法
//3. 可以不实现分类的全部方法
@interface MyTest (MyTestEx)  // 括号里的MyTestEx作为MyTest类的分类
-(int) add : (int) a;
-(int) sub : (int) a;
@end


@implementation MyTest (MyTestEx)
-(int) add : (int) a
{
 num1 += a;
}
-(int) sub : (int) a
{
 num1 -= a;
}
@end

// 调用
MyTest* p = [[MyTest alloc] init]; 
[p setTo : 1 set2 : 3];
[p add : 1];
[p print];
[p release];

// 输出
2/3


3. 协议
协议是多个类共享一个方法列表。 就有点象C++里的虚函数表
协议只负责声明, 实现由引用类负责

// 这是一个协议声明, 感觉就是vc里的接口声明
// interface NSCopying {
// void* copyWithZone(NSZone* zone) = 0;
// };
@protocol NSCopying
-(id)copyWithZone: (NSZone*)zone;
@optional // 该关键字后的方法可以不实现
-(void) outline;
@end

// 使用协议, 协议用尖括号包含起来, 放在类名或基类名称之后
// VC里应该是这样class CAddressBook : public CNSObject , public INSCopying {};
@interface AddressBook : NSObject <NSCopying>
@end
// 可以使用多个协议, 就象VC里的多重继承
// class CAddressBook : public CNSObject , public INSCopying , public INSCoding{};
@interface AddressBook : NSObject <NSCopying, NSCoding>
@end


 

posted @ 2012-02-11 15:34 wangkang 阅读(447) | 评论 (0)编辑 收藏

PaiMei(白眉)v1.2安装笔记
2011-12-9

--------------------
多次失败后的总结, python要用2.6版本, mysql最好用高版本, 本人用了最新的mysql5.5, 密码不能为空
集成包下载地址:

http://pan.baidu.com/share/link?shareid=2445567694&uk=2433228464
依赖包在install目录中
--------------------

1. 安装python3.2
2. 安装mysql
 mysql修改密码
  mysql修改,可在mysql命令行执行如下:
  mysql -u root mysql
  mysql> Update user SET password=PASSWORD(”new password”) Where user=’name’;
  mysql> FLUSH PRIVILEGES;
  mysql> QUIT

3. svn checkout http://paimei.goolecode.com/svn/trunk/

4. 修改下载目录中的__build_installer.bat
把python执行路径改成安装路径

5. 执行__build_installer.bat

6. 修改__install_requirements.py
写一个chang2to3.bat的文件, 内容如下
set mypath=d:\progra~1\python32
%mypath%\python.exe %mypath%\Tools\Scripts\2to3.py -w __install_requirements.py
详细参考http://woodpecker.org.cn/diveintopython3/case-study-porting-chardet-to-python-3.html#running2to3

----------------------------------------
上面是失败的案例, 因为wxPython只支持到2.7, 在官网上没有发现对3的支持
因此用python2.7来试试, 因为2.4找不到下载的地方了。

1. 在下载吧下载python2.7
http://www.xiazaiba.com/html/2049.html

2. 下载mysql

3. svn checkout http://paimei.goolecode.com/svn/trunk/

4. 修改下载目录中的__build_installer.bat
把python执行路径改成安装路径

5. 执行__build_installer.bat
 在当前目录中创建了两个新的目录dist, build
 没出问题的话会在dist目录中生成paimei的exe文件

6. 执行__install_requirements.py
 wxPython和mysqldb的地址不对, 需要手工下载, 其它能下载两个

7. http://www.wxpython.org/download.php#stable里下载wxPython2.8-win32-ansi-2.8.12.1-py27.exe
8.
下载mysqldb
http://www.codegood.com/archives/129%E4%B8%8B
MySQL-python-1.2.3.win32-py2.7.exe

9.下载ida pro5.5, 用看雪礼包dvd里的ida5.5

10. 修改IDA Pro的plugins目录下的python.disable为python.plw。

11. 安装上面下载的全部软件

12. 建表, 创建一个setup_mysql.bat, 内容如下
"D:\Program Files\Python27\python.exe" __setup_mysql.py localhost root pwd
运行后将在mysql建立paimei的数据库

13. 执行dist\PaiMei-1.2.win32.exe, pydbg等会安装到python下,作为lib

14. 运行uDraw, 写一个跑uDraw的bat, uDraw.bat
start "uDrawGraph" "D:\Program Files\uDraw(Graph)\bin\uDrawGraph.exe" -server 2542

15. 双击执行console\PAIMEIconsole.pyw, 或写一个run_paimei.bat
call uDraw.bat
start console\PAIMEIconsole.pyw

16. 提示pydbg不能import, 需要重新整pydbg,

 1) 下载  http://www.adintr.com/down/libs/libdasm-1.5.tar.gz
 2)  去libasm目录中的pydasm目录执行setup.py install
 如果提示unable to Find vcvarsall.bat, 说明当前vc版本低于2005
 找一个高版本的vc进行编译
 3) pyd应该就是dll,依赖里有python26.dll, 不编译的话, 找一个python26.dll拷贝到windows\system32下
 4) 用python调试器跟了一下, 提示26是冲突的dll, 因此27不能用在该版本。


-----------------------------------------------------------
由16可知, python27不能使用在paimei1.2上

把27卸了,重装了python26, 不装paimei框架, 竟然发现pydbg等模块都能测试通过, 很奇怪
双击console\PAIMEIconsole.pyw, 竟然能顺利执行了。晕

1. 下载python26版的ida python
http://bbs.pediy.com/attachment.php?attachmentid=39624&d=1267185909

2. 进入PAIMEIpstalker, 右键单击“Avaliable Targets”,选择“Add targets”,新建一个追踪目标,取名calc。

右键单击新添加的追踪目标,选择“Add Tag”。取名test1.【Tag用于区别一次指令追踪操作,可以在一个追踪目标下建立多个Tag以表示不同的追踪操作】

右键单击新添加的Tag,选择“Use for Stalking”

如不能添加, 重启paimei, 连接mysql立刻进行上述动作,选中的tag前面变成放大镜图标, 此时可成功.

3. IDA加载calc.exe,分析完成后,
使用Alt+9或者在IDA菜单中Edit——>Plguins——>IDApython中启动Paimei安装目录下的“pida_dump.py”脚本,
即将IDA分析的结果保存成Paimei所使用的数据格式pida文件。确定后选择full,然后保存在paimei\console中。

4. 单击Paimei的“Add Module”按钮,将刚才用IDA导出的静态代码读入Paimei

5. 执行calc.exe, 单击“Refresh Process List”按钮来选择已经启动的进程进行Attach
也可用“Browse”按钮来选择PE文件直接加载

6. 点”Start Stalking”按钮,开始指令追踪。

7. calc中做一些操作, 点”Stop Stalking”

8. 右键单击当前的tag选择“load hits”,
Paimei会将执行到的指令块读入并显示详细的信息;如果选择“Sync with uDraw”,
Paimei会在uDraw的界面下绘制刚刚执行过的指令块及其之间的调用关系。

使用详细参考:
http://hi.baidu.com/%BA%A3%CD%E5%D6%AE%CA%F701/blog/item/fea879d81546c8275982ddc3.html




 

posted @ 2011-12-25 13:13 wangkang 阅读(1910) | 评论 (0)编辑 收藏
/Files/wangkang2009/AllVersionPrj.rar

关键字: VC2008 to VC6    VC9toVC6 VC8toVC6 VC9toVC71

相信现在坚守Vc6和VC2003的人不多了, 不过作为一个老程序员, 还是必须坚守下去, 虽然已经越来越不容易了。
VC2008的mfc使用了大量的新库, 而且调整了一些编译语法, 如果碰到这样的程序, 只能是选择虚拟机, 装之。因为调整程序的时间远大于安装的时间。

当然, 大多数工程还是按照sdk的规范来开发的, 同时经过轻微的调整同样能在VC2003下或VC6下编译通过。

下面讲述一下转换步骤:
1、解压上面的包, 运行AllVersionPrj.exe , 拖拽目标sln到dlg中。  
2、选择转换成VC6工程, 将在目标目录中创建dsw和dsp, 不过会在后面加上71, 比如your.vcproj=>your71.dsp, 这是为了再转换成VC2003时不会覆盖
   掉原来的vcproj
3. 用VC2003打开dsw,直接转换成your71.sln工程
4. 手工调整编译及链接选项, 编译转换的sln工程, 可能会出PRECOMP_VC7_TOBEREMOVED文件找不到等错误, 对于UNICODE工程会报TCHAR转换错, 这些错误都是因为vcproj转换不彻底, 被插入了一些无用的标记,全目录搜索PRECOMP_VC7_TOBEREMOVED和$(NoInherit), 并把它们替换为空, 其它相似问题同样处理。

至此, 转换工作完成。



posted @ 2011-11-02 18:46 wangkang 阅读(4278) | 评论 (3)编辑 收藏
关键字: ida sig runtime libcmt.lib

这两天研究了一下ida的sig机制, 大体就是把lib导成pat, 然后pat再导成sig, 原理是字节匹配来确定函数名.
签名的细节这里就不研究了, 具体讲一下vc静态库的sig签名制作过程。

1. 简单的签名过程
   pcf libcmt.lib libcmt.pat
   sigmake libcmt.pat libcmt.sig
   如果没问题的话上面两句就可以搞定, 但问题是中间会出错.

2.  把lib转成obj来进行签名, 这个转换过程比较复杂, 这里通过bat来处理
    把附件压缩包/Files/wangkang2009/bin.rar里的内容解到ida\flair\bin中
    修改run.bat里的目标lib名称, 不是vc lib目录的要修改lib2obj.bat,  转换使用的是2003里的lib.exe , 因此还需要设置vc2003的路径在lib2obj.bat里,
    开始执行run.bat
    中间会创建临时目录和临时文件, bat结束后会删除。

3. 运行结束后会生成exc文件, 修改exc后再次运行, 简单的把前面带;的注释行删除即可. 再次运行
   sigmake -n"vc6 mt runtime lib" libcmt\*.pat vc6libcmt.sig
   最后可发现sig文件建立。

posted @ 2011-10-17 18:51 wangkang 阅读(869) | 评论 (0)编辑 收藏

这本来是一个老掉牙的问题,  结果在网上一搜竟然没有什么好的解决方案, 还是自己来吧,  如果你觉得这篇文章有点帮助, 请给点回复.


1. 分析任务管理器使用的api, 经查其使用的api为NtQuerySystemInformation, 查msdn可知该api可取得进程信息链表

2. 使用全局钩子注入任务管理器, 然后api hook 上述函数, 把当前要隐藏的进程项从链表中删除

LONG WINAPI MyNtQuerySystemInformation(
                   SYSTEM_INFORMATION_CLASS SystemInformationClass,
                   PVOID SystemInformation,
                   ULONG SystemInformationLength,
                   PULONG ReturnLength
                   )
{
    LONG lRet 
= RealNtQuerySystemInformation(SystemInformationClass, SystemInformation,
        SystemInformationLength, ReturnLength);

    
if(SystemInformationClass == SystemProcessInformation) {

        PSYSTEM_PROCESS_INFORMATION     pCurrent;
        PSYSTEM_PROCESS_INFORMATION        pPrev;
        
int cbOffset = 0;
        BOOL bFind 
= FALSE;

        
do 
        {
            bFind 
= FALSE;
            pCurrent 
= (PSYSTEM_PROCESS_INFORMATION)&((LPBYTE)SystemInformation)[cbOffset];
            
if(pCurrent->UniqueProcessId != 0) {
                LPTSTR pszImageName 
= *(LPTSTR*)((LPBYTE)pCurrent + 0x3c);
                
if(pszImageName ) {
                    
if( lstrcmpi(pszImageName, _T("your.exe")) == 0 
                            )
                    {
                        bFind 
= TRUE;
                    }
                }
            }

            
if(!bFind)
                pPrev 
= pCurrent;
            
else {
                pPrev
->NextEntryOffset += pCurrent->NextEntryOffset;
            }

            cbOffset 
+= pCurrent->NextEntryOffset;

        } 
while(pCurrent->NextEntryOffset);
    }
    
    
return lRet;
}
posted @ 2010-08-13 16:44 wangkang 阅读(2826) | 评论 (10)编辑 收藏

错误使用api输入输出参数引起的问题

今天使用CRegKey::QueryBinaryValue碰到一个问题, 我是这样使用的,
// 遍历一个目录里的值
for(DWORD i=0; i<cValues; i++) {
 TCHAR achValue[10] = {0};
 DWORD cchValue = 10;
 DWORD dwRet = RegEnumValue(reg.m_hKey, i, achValue,
  &cchValue,
  NULL,
  NULL,    // &dwType,
  NULL,    // &bData,
  NULL);   // &bcData

 if(dwRet == ERROR_SUCCESS) {
  memset(buffer, 0, cbMaxValueData);
  DWORD len ;
  if(reg.QueryBinaryValue(achValue, buffer, &len) == ERROR_SUCCESS) {
  }
 }
}

当循环的第一次时能够取到数据, 而第二次时reg.QueryBinaryValue返回错误, 粗一看,
这是很费解的事, 为什么第一次能取到数据, 而第二次取不到, 仔细查看传入的3个参数,好像没什么问题,
buffer也足够大, 应该没有问题的, 观察返回的错误号是234, 错误解释是More data is available.
中文意思是更多的数据是可用的, 看这意思好像是len的问题, 如果是len的问题, 为什么第一次能成功而第二次失败了,
再次仔细观察len, 第一次len的值比第二次len的值要小, 这好像可以解释More data is available了,感觉应该len的问题了,
把msdn的RegQueryValueEx检索出来, 果然len那个参数是[in,out]属性,把 DWORD len ;改为DWORD len = cbMaxValueData; 后一切正常。

现在可以解释为什么第一次成功,而第二次失败了, len不赋值编译器应该给赋了一个随机值, 第二次初始化时编译器并没有清理
堆栈, 用的是第一次取得的值, 而第二次需要的len比第一次的大, 因此报234的错误。

总结上面的错误, 对于这种需要计算buffer长度的api, 最好给len附上buffer的长度丢入api, 这样基本上不会出错了。

这个问题竟然弄了一小时, 特此写下这篇小文加深印象。

posted @ 2010-03-30 13:51 wangkang 阅读(453) | 评论 (0)编辑 收藏

如何创建js内部对象

1. 使用IActiveScript::AddNamedItem添加需要响应的内部对象
 HRESULT hr;
 IActiveScript* pScript;
 CLSID clsid;
 // Search for LanguageID and create instance of script engine
 if (SUCCEEDED(CLSIDFromProgID(L"JScript", &clsid)))
 {
  // If this happens, the scripting engine is probably not properly registered
  hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IActiveScript, (void **)&pScript);
  if(SUCCEEDED(hr)) {
   pScript->AddNameItem(L"newname", SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE);
   pScript->Release();
  }
 }

2. 绑定COM到新的名字对象上, 创建一个新的com对象, 比如接口名叫INewName
 实现一个IActiveScriptSite接口, 并实现里面的GetItemInfo方法
 class  CMyActiveScriptSite : public IActiveScriptSite
 {
  HRESULT GetItemInfo(
      LPCOLESTR pstrName,     // address of item name
      DWORD dwReturnMask,     // bit mask for information retrieval
      IUnknown **ppunkItem,   // address of pointer to item's IUnknown
      ITypeInfo **ppTypeInfo  // address of pointer to item's ITypeInfo
  )
  {
   if(_wcsicmp(L"newname", pstrName) == 0)
   {
    if (dwReturnMask & SCRIPTINFO_ITYPEINFO)
    {
     LPUNKNOWN lpUnknown = NULL;
     // 获取INewName
     // ...
     lpUnknown = pNewName;
     
     // Use IProvideClassInfo to get ITypeInfo of coclass!
     IProvideClassInfo *pci = NULL;
     HRESULT hr = lpUnknown->QueryInterface(IID_IProvideClassInfo, (void**)&pci);
     if (SUCCEEDED(hr) && pci)
     {
      hr = pci->GetClassInfo(ppti);
     }

     // Release interface
     if (pci)
      pci->Release();

     if (FAILED(hr))
      return E_FAIL;
    }

    if (dwReturnMask & SCRIPTINFO_IUNKNOWN)
    {
     *ppiunkItem = lpUnknown;
     (*ppiunkItem)->AddRef();    // because returning
    }
   }
  }
 }

 CMyActiveScriptSite* pSite = new CMyActiveScriptSite;
 pScript->SetScriptSite(pSite);

3. 脚本里使用INewName的接口, 比如INewName实现了run这个接口
<SCRIPT LANGUAGE="JavaScript">
<!--
 newname.run();
//-->
</SCRIPT>
最终脚本将把newname看成和window一样的内部对象

posted @ 2010-01-12 20:35 wangkang 阅读(458) | 评论 (0)编辑 收藏
最近要分析一程序的数据收发, 先准备用截包软件WireShark来分析, 不过看了一会儿不得要领, 不是太会用它的filter, 还是用windbg来分析吧, 因此写一脚本来截取数据包, 相当于根据SOCKET句柄来过滤包。

$$------------------------------------------------------------
$$ windbg script 
$$ Usage: $$
>a<fsocket.txt dllname
$$ example: $$
>a<d:\script\fsocket.txt module 1
$$ analyze client socket connetion
$$ 
break connect/send/recv function
$$ 
2009-11-11
$$ write by wangkang
$$ blog: http:
//www.cppblog.com/wangkang2009
$$------------------------------------------------------------


.
if(${/d:$arg1})
{
    bc
*

    $$ calc the length of module
    $$ poi(${$arg1}
+poi(${$arg1}+3c)+50);

    $$ judge the module 
is loaded.
    r $t5
=0

    bp ws2_32
!connect ".echo <<<<<<<<<<<<<<<<<<<<<<;.if(@$t5=0){.foreach(obj {lm1mo}){.if(0==$sicmp(\"${obj}\", \"${$arg1}\")){r $t5=1;.echo >>>>>>>>>>>>>>;}}}; .if(@$t5=1){.echo -------->>>>>>>;r $t9=poi(${$arg1}+poi(${$arg1}+3c)+50); ? @$t9;dds esp l1;? poi(esp);.if(poi(esp)>${$arg1} and poi(esp)<${$arg1}+@$t9) {.echo ------<<<;r $t3=poi(esp+4);.logappend c:\\log.txt;.echo <------connect;.for(r $t1=poi(esp+8)+4; @$t1<poi(esp+8)+8;r $t1=@$t1+1){r $t2=by(@$t1);.printf /D \"%d.\", @$t2;};.echo \"<---ip\";dds @esp l1;.logclose;bc0;};};gc;"

    bp ws2_32
!recv ".if(@$t5=1){.if(poi(esp+4)=@$t3) {r $t1=poi(esp+8);gu;.if(@eax>0){.logappend c:\\log.txt;.echo <------recv;db @$t1 l@eax;.logclose;};g};};gc;"

    .
if(${/d:$arg2})
    {
        bp wsock32
!recv  ".if(@$t5=1){.if(poi(esp+4)=@$t3) {r $t1=poi(esp+8);gu;.if(@eax>0){.logappend c:\\log.txt;.echo <------recv;db @$t1 l@eax;.logclose;};g};};g;"
    }

    bp ws2_32
!send ".if(@$t5=1){.if(poi(esp+4)=@$t3) {r $t1=poi(esp+c);.logappend c:\\log.txt;.echo <------send;db poi(esp+8) l@$t1;.logclose;};};gc;"

}

recv函数有些会在WSOCK32模块中发生, 对于这种情况, 调用时使用第二个参数, 如在ws2_32中发生则不用第二个参数。
脚本开始时会清除全部断点, 使用前先把原有断点保存。

执行后, 结果会输出到c:\log.txt
posted @ 2009-11-14 11:40 wangkang 阅读(2285) | 评论 (0)编辑 收藏
1. 下载ASPack2.12 , 压缩一Notepad.exe
2. 用od1.1载入加壳后的notepad, 调试选项->事件->主模块入口
3. 使用esp平衡法, 载入后esp指向7ffc4, 命令行里输入hw 7ffc0(注: 加密与解密一书中用的是7ffc4)
4. F9后触发中断, esp为7ffc0, 里面的值就是oep, 100739d
5, 在代码区Ctrl+G, 输入100739d, 然后在100739d处F2
6, 再次F9后, 代码停在100739d, 调用ollyDump, 然后确定即可.
7, dump出的文件不用修改即可运行, 比原始文件要大, 同时用ida也匹配不上符号了, 不过看了一下函数地址都是对的,
   import表也是对的.
posted @ 2009-09-01 11:59 wangkang 阅读(293) | 评论 (0)编辑 收藏
/Files/wangkang2009/sym.rar

1. 安装Windbg

2. 把windbg安装后的目录放到环境变量的Path中

3. 下载sym.rar , 解压缩到c:\sym

4. 执行c:\sym\getsym.bat, 出现一个cmd框, 此时下载进行中..., 不能关闭该框, 下载完成
     后该框会关闭, 下载需要较长时间, 视网速而定.

5. ida 使用windbg下载的符号
   修改ida目录下的cfg\pdb.cfg
   把符号目录做如下设置, 注意要有双引号和两个斜杠
   PDBSYM_DOWNLOAD_PATH    = "c:\\sym";


本博客所有文章均为原创,谢绝转载!!!
posted @ 2009-08-13 10:59 wangkang 阅读(1561) | 评论 (0)编辑 收藏
仅列出标题
共2页: 1 2