48_SDK概念

Sdk课程安排

  1. sdk 5-6节课入门原理
  2. 界面开发
  3. Sdk是三阶段的基础,从逆向的角度来讲很重要,windows系统提供的最底层的接口
  4. 意义:不会vb,dephi,照样可以运行它们的程序
  5. 事件驱动,消息响应是一种设计思想

Windows sdk编程入门

  • API(application programming interface):应用程序编程接口,输入输出设备被操作系统接管了,通过应用程序来操作。系统不希望操作者知道它内部的结构具体定义
  • 内核对象:操作系统的内部受保护,只能通过API来修改,如同二叉树提给给别人只能通过函数来修改,这种二叉树对象称为内核对象
  • 用户和内核模式
    • 80386芯片的4个权限级别:0-3,低权限访问高权限会使程序崩溃,解决了安全问题。
    • Windows系统所使用的两个权限级别:0,3。管态(0环)目态(3环)。windows为什么没有1,2环,因为windows只是用0环和3环,从商业来说微软不想太依赖cpu指令集的权限划分
    • 用户模式下的限制:用户模式下不能访问内核下的代码和数据
    • 单片机没有区分权限,用户的代码可以随意进出操作系统,早期的dos时代
  • 句柄:操作系统的内核对象的唯一标识,一个id编号而已
  • 消息机制
    • 解决问题:输入来说,应用程序知道怎么处理,不知道何时来,操作系统知道什么时候来,不知道怎么处理。回调函数:应用程序的函数给操作系统来调用。应用程序函数指针知道做什么,操作系统函数指针指向应用程序的做什么。
    • 系统将各种输入封装成一个消息结构体,包含输入的种类和输入的相关信息,通过回调的方式调用应用程序实现的输入处理函数称为消息机制

区别、辨析windows程序和console程序

  • Sdk程序是多任务的程序,可以有多个线程,console程序是单任务的程序
    • Windows多任务的实现:80386对多任务操作系统的支持,cpu有多个线程,切换速度快到肉眼不能识别
  • 入口函数
    • _tmian和WINAPI WinMain
    • 参数也不同
  • 链接方式
    • SUBSYSTEM
      • Console
      • Windows

认识windows程序的参数

  • hInstance:应用程序当前实例句柄,关闭随机基质,是一个地址。不同的进程独立的内存
  • hPrevInstance:16位应用程序
  • lpCmdLine:命令行参数
  • nCmdShow:窗口显示状态

进程

  • 给线程提供各种资源的
  • 虚拟内存:在32位应用程序当前,这个进程拥有4g内存。高地址内存:0x80000000-0xffffffff,2g系统空间;低地址内存:0x00000000-0x7fffffff,2g用户空间。实际上低64k也不能是用。对于32位操作系统来说最多物理内存只能有2^32==4g物理内存。
  • 进程间的内存隔离:进程虚拟内存映射到物理内存不同的位置,进程与进程之间的内存是相互隔离的
  • 启动顺序:可执行文件的内容往虚拟内存中拷贝,首地址就是main函数的第一个参数

MessageBox

  • 库:SDK:windows user interface
    • hWnd:父窗口句柄,如果没有就写null
    • lpText:0结尾的字符串,文字
    • lpCaption:0结尾字符串,标题
    • uType:消息盒子类型
  • MessageBox实际上是一个宏定义,W是宽字节版本,A是ascii版本
  • Windows6000多个涉及字符串的api都有两个版本,ascii码版本和wchar版本
  • 为了兼容是用tchar.h,_T,没有定义_UNICODE就不加L,windows api的宏少一个下划线。要放在头文件前或者编译选项里面,或者直接修改字符集。或者是用windows提供的宏TEXT,UNICODE
  • HWND:H:handle,WND-windows
  • HPROCESS H-handke PROCESS-process
  • HINSTANCE H-handle INSTANCE-instance
  • HICON H-handle ICON-icon
  • 看到H,这个类型所定义的对象是句柄,WND指的的是窗口对象,Process进程对象,Instance是应用实例对象,Icon-图标
  • LPCWSTR
    • LP:long pointer指针(32位),P(16位)
    • C:const
    • W:wchar_t
    • STR:说明性字符串
  • NULL_terminated:说明性宏
  • _In_opt:说明性输入宏
  • WINAPI:除了一个之外都是_stdcall调用约定
  • Struct name##__ *name,程序可读性,扩展方便

作业

  1. 将Demo中的WinMain函数改为C语言的main,并在链接的时候用/subsystem:console参数会有什么不同。

调用约定不同,WINAPI是_stdcall,控制台程序是_cdcall

  1. 不包含Windows.h,弹框 “Hello, world!”

编译不通过

3. <winnt.h>拆分

  1. typedef _Null_terminated_ CHAR *NPSTR, *LPSTR, *PSTR;

_Null_terminated_:是说明以零结尾的字符串,是说明性的宏

NPSTR: N- NULL 以零结尾 P-Point指针 STR:说明是字符串 ,NPSTR本质上是个char*

LPSTR: L-long长的 32位,P-Point 指针,STR-说明是字符串,LPSTR本质上是个char*

PSTR: P-Point 指针,STR说明是字符串,PSTR本质上是个char*

  1. typedef _Null_terminated_ PSTR *PZPSTR;

_Null_terminated_:是说明以零结尾的字符串,是说明性的宏

PZPSTR: P-Point 指针,Z-Zero以零结尾,P-Point 指针,STR:说明是字符串,PZPSTR本质上是个char**

  1. typedef _Null_terminated_ CONST PSTR *PCZPSTR;

_Null_terminated_:是说明以零结尾的字符串,是说明性的宏

PCZPSTR: P-Point 指针,C-Const 常量,Z-Zero 以零结尾,P-Point 指针,STR说明是个字符串,PCZPSTR本质上是个const char** 指针指向的内容不能修改

  1. typedef _Null_terminated_ CONST CHAR *LPCSTR, *PCSTR;

_Null_terminated_:是说明以零结尾的字符串,是说明性的宏

LPCSTR: L-long 长的 32位,P-Point 指针,C-const 常量,STR 说明是个字符串,LPCSTR本质上是个const char*,指针指向的内容不能修改

PCSTR: P-Point 指针,C-Const 常量,STR:说明是个字符串,PCSTR的本质是一个const char*,指针所指内容不能修改

  1. typedef _Null_terminated_ PCSTR *PZPCSTR;

_Null_terminated_:是说明以零结尾的字符串,是说明性的宏

PZPCSTR: P-Point 指针,Z-Zero 零结尾,P-Point 指针,C-const 常量,STR 说明是个字符串,PZPCSTR本质上是一个const char**

  1. typedef _Null_terminated_ CONST PCSTR *PCZPCSTR;

_Null_terminated_:是说明以零结尾的字符串,是说明性的宏

PCZPCSTR: P-Point 指针,C-const 常量,Z-Zero 以零结尾,P-Point 指针,C-Const 常量,STR 说明是字符串 说明性,PCZPCSTR本质上是个const const har*

  1. typedef _NullNull_terminated_ CHAR *PZZSTR;

_NullNull_terminated_ :以两个零结尾的字符串,是说明性宏

PZZSTR:P-Point 指针,Z-Zero 零,Z-Zero:零结尾,STR:说明是字符串,PZZSTR本质上是以2个零结尾的字符串(char *)

  1. typedef _NullNull_terminated_ CONST CHAR *PCZZSTR;

_NullNull_terminated_ :以两个零结尾的字符串,是说明性宏

PCZZSTR: P-Point 指针,C-Const 常量,Z-Zero 零 ,Z-Zero 以零结尾,STR 说明是个字符串,PCZZSTR本质上是个以两个零结尾的常量字符串(const char *)

作业

1.不包含Windows.h,弹框 “Hello, world!”

 //test.cpp
//#include 
#include 

#define TEST


#ifdef TEST

#define WINAPI __stdcall
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
DECLARE_HANDLE(HINSTANCE);
typedef wchar_t WCHAR;
typedef char CHAR;
typedef CHAR* LPSTR, * PSTR;
#define CONST               const
typedef CONST CHAR* LPCSTR, * PCSTR;
typedef CONST WCHAR* LPCWSTR, * PCWSTR;

typedef unsigned int        UINT;

#define DECLSPEC_IMPORT __declspec(dllimport)

#define WINUSERAPI DECLSPEC_IMPORT


DECLARE_HANDLE(HWND);
DECLARE_HANDLE(HHOOK);

#define MB_OK                       0x00000000L
#define MB_OKCANCEL                 0x00000001L
#define MB_ABORTRETRYIGNORE         0x00000002L
#define MB_YESNOCANCEL              0x00000003L
#define MB_YESNO                    0x00000004L
#define MB_RETRYCANCEL              0x00000005L


#define _Pre_valid_impl_
#define _Deref_pre1_impl_(p1)

#define _Deref_pre_readonly_                    _SAL1_1_Source_(_Deref_pre_readonly_, (), _Deref_pre1_impl_(__readaccess_impl_notref))
#define _Group_impl_(annos)
#define _Pre1_impl_(p1)
#define _SA_annotes3(n,pp1,pp2,pp3)
#define _SAL_nop_impl_ X
#define _Group_(annos)                 _Group_impl_(annos _SAL_nop_impl_)

#define _SAL1_1_Source_(Name, args, annotes) _SA_annotes3(SAL_name, #Name, "", "1.1") _Group_(annotes _SAL_nop_impl_)
#define _SAL2_Source_(Name, args, annotes) _SA_annotes3(SAL_name, #Name, "", "2") _Group_(annotes _SAL_nop_impl_)

#define _In_                            _SAL2_Source_(_In_, (), _Pre1_impl_(__notnull_impl_notref) _Pre_valid_impl_ _Deref_pre1_impl_(__readaccess_impl_notref))
#define _In_opt_                        _SAL2_Source_(_In_opt_, (), _Pre1_impl_(__maybenull_impl_notref) _Pre_valid_impl_ _Deref_pre_readonly_)

extern "C" //名称粉碎的问题,需要是用.c
{
    WINUSERAPI
        int
        WINAPI
        MessageBoxA(
            _In_opt_ HWND hWnd,
            _In_opt_ LPCSTR lpText,
            _In_opt_ LPCSTR lpCaption,
            _In_ UINT uType);
    WINUSERAPI
        int
        WINAPI
        MessageBoxW(
            _In_opt_ HWND hWnd,
            _In_opt_ LPCWSTR lpText,
            _In_opt_ LPCWSTR lpCaption,
            _In_ UINT uType);
}
#ifdef UNICODE
#define __TEXT(quote) L##quote
#define MessageBox  MessageBoxW
#else
#define __TEXT(quote) quote
#define MessageBox  MessageBoxA
#endif

#define TEXT(quote) __TEXT(quote)

#endif



int WINAPI WinMain(HINSTANCE hInstance,      // handle to current instance
	HINSTANCE hPrevInstance,  // handle to previous instance
	LPSTR lpCmdLine,          // command line
	int nCmdShow              // show state
)
{

	MessageBox(
		NULL,
		TEXT("Hello World!"),
		TEXT("Hello SDK"),
		MB_YESNO);
	return 0;
}

0 条评论
发表一条评论