在Debian Linux下编译第一个objc程序

 

首先,我们要安装相应的程序:

apt-get install gcc gobjc gcc g++ gnustep libgnustep-gui-dev

然后编写一个hello.m文件:

连hello.m都是抄来的,哈哈,程序如下:

#import <Foundation/Foundation.h>

@interface HelloWorld : NSObject

- (void) hello;

@end

@implementation HelloWorld

- (void) hello {

NSLog(@”hello world!”);

}

@end

int main(void) {

HelloWorld *hw = [[HelloWorld alloc] init];

[hw hello];

[hw release];

}

然后就是编译了:

编译成.o文件:

gcc -fconstant-string-class=NSConstantString -I /usr/include/GNUstep/ -c hello.m

链接:

gcc hello.o -o hello -lgnustep-base

一些方便的设置:

在bashrc中添加一条:

alias objcc=’gcc -fconstant-string-class=NSConstantString -I /usr/include/GNUstep/ -lgnustep-base’

以上命令就简化啦:

objcc –o hello hello.m

运行:

$ ./hello

2010-08-12 01:03:23.930 hello[1642] hello world!

用vs2010自带工具制作文件证书

以便给自己的程序签名,呵呵。

当然,这样签 发的程序在别人那是不被信任的。除非把自己的根证书给别人安装。

用命令行,使用如下命令:

makecert  -pe -ss swigger -n “CN=swigger.net” -sv swigger_root.pvk -r swigger_root.cer

这里会弹出框要求密码,输入密码 root_pwd 或其它密码。共输入3次,前两次设置,后一次验证。

makecert -is swigger -n “CN=swigger file sign” -$ commercial -ic swigger_root.cer -sv fs.pvk fs.cer

这里继续弹出要密码,设置为 pwd2 或其它密码。共输入三次,两次设置,一次确认。还会弹出第四次要密码,要输入上一步设置的密码 root_pwd (或其它值)。

cert2spc fs.cer fs.spc

以下两条命令的pwd2是第二步设置的密码,如果不是pwd2,要换成其它值。

pvk2pfx -pvk fs.pvk -pi pwd2 -spc fs.spc -pfx fs.pfx -f

signtool sign /t http://timestamp.verisign.com/scripts/timstamp.dll  /v  /f fs.pfx /p pwd2  filename.exe

签名完成后,把swigger_root.cer安装到受信用的根证书,就显示文件正常签名了。

为android 生成 native 程序

 

为android生成原生应用程序,不难啊。
初始条件:安装android的ndk,比如目前最新的 android-ndk-r3。(2010-03版)
我的目录结构:
~/android-ndk-r3
~/android-ndk-r3/temp  这个是当前工作目录。

Step1: 写两个文件:
hello.c:

#include <stdio.h> int main() {     printf("hello, world\n");     return 0; }

start.c

#include <stdlib.h> extern int main(int argc, char **argv); void _start(int argc, char **argv) {     exit (main (argc, argv)); }

Step2: compile

../build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/arm-eabi-gcc \ -I ../build/platforms/android-3/arch-arm/usr/include/  -c hello.c ../build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/arm-eabi-gcc \ -I ../build/platforms/android-3/arch-arm/usr/include/  -c start.c

Step3: link

../build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/arm-eabi-ld --entry=_start \ --dynamic-linker /system/bin/linker -nostdlib     -rpath /system/lib  \ -L ../build/platforms/android-3/arch-arm/usr/lib/  \ -rpath ../build/platforms/android-3/arch-arm/usr/lib/    \ -lc -o hello hello.o start.o

Step4: execute:

adb push hello /data/hello adb shell cd /data chmod 755 ./hello ./hello hello, world

值得注意的一点是,在/sdcard目录下,程序运行不起来。我一开始还以为是没编好呢。后来扔到/data目录下,才成功跑起来。

调试XP/2k3的安装过程

 在安装的源盘根目录提供一个winnt.sif,写上:

[SetupData]
OsLoadOptions = “/noguiboot /fastdetect /debug /debugport=com1 /baudrate=115200 /break”

即可。

不过XP的setupldr.bin不支持这个,要win2k3的才行。(推荐sp1。sp2加载ramdisk有卡住bug)

regsavekey (ntsavekey) 异常的调试过程

结论非常简单,要先调用  NtInitializeRegistry. 参数见 wrk 中的 ntregapi.h

过程比较复杂,在smss.exe中用bootexecute启动的native程序里,调用 ntsavekey达不到想要的结果。

NtSaveKey会返回0,也就是没有错误。结果文件也会生成,生成的大小看起来也是对的。但是文件里面没有任何内容。所有字节都是0。

调试过程:

1. smss.exe启动的native程序是非常早的,可能是系统还有什么没准备好。试着替换其它程序而不是被smss.exe启动,来看看。

2. 替换winlogon.exe,发现能保存。

3. 替换 csrss.exe,发现也能保存。

4. 由于启动时候,smss创建csrss.exe ,后者再创建winlogon.exe。因此可以知道,在smss.exe调用native exe之后,启动csrss.exe之间,一定发生了什么事,使得ntsavekey在其前不能运行,其后可以运行。

5. 写一个简单的DLL,提供一个函数调用ntsavekey做测试,用lordpe把此DLL添加到smss.exe的依赖里。

6. WINDBG调试smss.exe启动native app后的路径,它每调几个函数就试下DLL中提供的函数看看ntsavekey是否正常。

7. 调试发现,在 NtInitializeRegistry之前,ntsavekey出现异常结果,之后,正常。

8. 结论: NtSaveKey需要用NtInitializeRegistry初始化注册表。

转载: windbg 如何在内核模式调试用户空间的程序

1:使用!process 0 0 获取用户空间的所有的进程的信息

 !process 0 0

**** NT ACTIVE PROCESS DUMP ****
    PROCESS 80a02a60  Cid: 0002    Peb: 00000000  ParentCid: 0000
    DirBase: 00006e05  ObjectTable: 80a03788  TableSize: 150.
    Image: System

 。。。。。

2:使用.process /p + 你需要断的应用程序的EProcess地址切换到应用程序的地址空间

   例如:

 .process  /p  0x80a02a60

3:重新加载user PDB文件

     .reload /f /user

4:使用非侵入式的切换进程空间

    .process /i /p 0x80a02a60

5:下应用层断点  bp        bu      都可以

原文:http://blog.csdn.net/purplethunder/archive/2009/04/04/4048379.aspx

另外顺便证下在windbg调试时强制调用一个函数:(设函数名是 test_reg)

r esp=esp-4 ; ed esp eip ; r eip = test_reg

vs中有趣的 windows message compiler

vs自带了一个mc.exe的程序,这个东西鲜有人知,它就是windows的message compiler程序。

mc编译mc代码,把它转变了一个bin格式的文件,放到资源中加载。在使用 windows event log , formatmessage的时候,就用得上这个消息了。formatmessage 有一个类似于 printf的形式的格式化能力。不过是用%1,%2这样的字眼,而不是%s,%d。这种%1,%2的形式理适合国际化。

codeproject上有一篇关于message compiler的文章:  http://www.codeproject.com/KB/system/mctutorial.aspx

windows kernel有不少地方使用mc格式的文本。比如windows 在安装的时候,提示欢迎,格式化等的文字都来源于安装盘smss.exe的message resource里。

生成的 .bin 文件格式;

binfile =  dword x + idgroups[x] + message[]

idgroup = dword startid + dword endid  + dword offset_to_message

message = dword sizeof(message) + char text[]

variant 变量表

老是要查头文件,又排得不整齐,排一份如下:

LONGLONG      llVal;        /* VT_I8                */ LONG          lVal;         /* VT_I4                */ BYTE          bVal;         /* VT_UI1               */ SHORT         iVal;         /* VT_I2                */ FLOAT         fltVal;       /* VT_R4                */ DOUBLE        dblVal;       /* VT_R8                */ VARIANT_BOOL  boolVal;      /* VT_BOOL              */ SCODE         scode;        /* VT_ERROR             */ CY            cyVal;        /* VT_CY                */ DATE          date;         /* VT_DATE              */ wireBSTR      bstrVal;      /* VT_BSTR              */ IUnknown *    punkVal;      /* VT_UNKNOWN           */ IDispatch *   pdispVal;     /* VT_DISPATCH          */ wirePSAFEARRAY parray;      /* VT_ARRAY             */ BYTE *        pbVal;        /* VT_BYREF|VT_UI1      */ SHORT *       piVal;        /* VT_BYREF|VT_I2       */ LONG *        plVal;        /* VT_BYREF|VT_I4       */ LONGLONG *    pllVal;       /* VT_BYREF|VT_I8       */ FLOAT *       pfltVal;      /* VT_BYREF|VT_R4       */ DOUBLE *      pdblVal;      /* VT_BYREF|VT_R8       */ VARIANT_BOOL *pboolVal;     /* VT_BYREF|VT_BOOL     */ SCODE *       pscode;       /* VT_BYREF|VT_ERROR    */ CY *          pcyVal;       /* VT_BYREF|VT_CY       */ DATE *        pdate;        /* VT_BYREF|VT_DATE     */ wireBSTR *    pbstrVal;     /* VT_BYREF|VT_BSTR     */ IUnknown **   ppunkVal;     /* VT_BYREF|VT_UNKNOWN  */ IDispatch **  ppdispVal;    /* VT_BYREF|VT_DISPATCH */ wirePSAFEARRAY *pparray;    /* VT_BYREF|VT_ARRAY    */ wireVARIANT * pvarVal;      /* VT_BYREF|VT_VARIANT  */ CHAR          cVal;         /* VT_I1                */ USHORT        uiVal;        /* VT_UI2               */ ULONG         ulVal;        /* VT_UI4               */ ULONGLONG     ullVal;       /* VT_UI8               */ INT           intVal;       /* VT_INT               */ UINT          uintVal;      /* VT_UINT              */ DECIMAL       decVal;       /* VT_DECIMAL           */ DECIMAL *     pdecVal;      /* VT_BYREF|VT_DECIMAL  */ CHAR *        pcVal;        /* VT_BYREF|VT_I1       */ USHORT *      puiVal;       /* VT_BYREF|VT_UI2      */ ULONG *       pulVal;       /* VT_BYREF|VT_UI4      */ ULONGLONG *   pullVal;      /* VT_BYREF|VT_UI8      */ INT *         pintVal;      /* VT_BYREF|VT_INT      */ UINT *        puintVal;     /* VT_BYREF|VT_UINT     */

透明窗口,连鼠标键盘事件也不接受,全透明

windows的透明窗口,如果设置了LWA_ALPHA和WS_EX_TRANSPARENT,就会连鼠标键盘事件也给透明过去,这个功能还不错。可以在屏上显示水印。

关键代码:

SetWindowLong(m_hWnd, GWL_EXSTYLE, WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST);
 SetLayeredWindowAttributes(m_hWnd, RGB(0,0,0), 120, LWA_ALPHA);
 SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW);

demo代码:

static LRESULT WINAPI UIWndProcBase(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {  if (msg == WM_PAINT)  {   PAINTSTRUCT ps;   BeginPaint(hWnd, &ps);   //OnPaint(ps.hdc);   EndPaint(hWnd, &ps);  }  else if (msg == WM_DESTROY)  {   PostQuitMessage(0);  }  return DefWindowProc(hWnd, msg, wParam, lParam); } void UIRun() {  WNDCLASSEX wc = {sizeof(wc)};  wc.hInstance     = GetModuleHandle(0);  wc.lpszClassName = _T("uiclassname");  wc.lpfnWndProc   = &UIWndProcBase;  wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  RegisterClassEx(&wc);  wstring ws = L"aaabbcd";  HWND hParent = CreateWindowExW(WS_EX_TRANSPARENT, _T("EDIT"), _T(""),  WS_POPUP, 0, 0, 100, 100, 0, NULL, wc.hInstance, NULL);  HWND m_hWnd = CreateWindowEx(0, wc.lpszClassName, ws.c_str(),  WS_POPUP, 0, 0, 100, 100,   hParent, NULL, wc.hInstance, NULL);  SetWindowLong(m_hWnd, GWL_EXSTYLE, WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST);  SetLayeredWindowAttributes(m_hWnd, RGB(0,0,0), 120, LWA_ALPHA);  SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW);  MSG msg;  while (GetMessage(&msg, 0, 0, 0))  {   TranslateMessage(&msg);   DispatchMessage(&msg);  } } int main() {  UIRun();  return 0; }

masm造weak symbol

masm或ml.exe可以用alias造weak external symbol,这样可以起到链接时有就选用户提供的,无就选系统默认的这样一个功能。这个语法很简单,但不好找。以前找了又忘了,特记下:

alias <sym2> = <sym1>

这次是在这里搜到的:

http://rs1.szif.hu/~tomcat/win32/win32asm.txt