2010-01-11

pygtk 异步显示对话框

需求是这样,我有一个主窗口,有自己的事情做,同时需要监视一个文件,如果有了变动就蹦个对话框出来,一开始的想法是

def handler():
dialog = gtk.MessageDialog(...)
dialog.run()
dialog.destroy()

gobject.threads_init()
gtk.gdk.threads_init()

gtk.io_add_watch(source, gobject.IO_IN, handler)
xxx_window.show()
gtk.main()

结果是对话框能显示出来,但是点击ok之后就卡死了,ok按钮也保持在“按下”的状态

后来看到了http://old.nabble.com/Deadlock-problem-when-calling-messagebox-function-with-idle_add-td25027865.html

于是在handler首尾分别加上gtk.gdk.threads_enter() 和 gtk.gdk.threads_leave() 就可以了

2010-01-10

内存错误调试工具 valgrind

偶然从某论坛看到的

valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out

目前只会这么一种用法,但是一下子就找到了病根,太棒了!

以后再研究研究。

2010-01-09

GameConqueror 0.09 -- Linux 游戏作弊工具

你是否喜欢游戏修改?
你是否一直在寻找`CheatEngine for Linux`?
那么你不该错过:


Gameconqueror 是一款Linux游戏修改工具,用PyGTK写成,以scanmem作为后端。

我的目标是实现CheatEngine的大多数功能,成为名副其实的`CheatEngine for Linux`

现在已经实现了基本的搜索功能,支持不同的数据类型和搜索类型,如下:

数据类型:不同长度的类型:int{8/16/32/64}, float{32/64},未知长度的类型:int, float, 未知类型:number, 字节串和字符串:bytearray, string
搜索类型:相等,大于,小于,变化,未变,增大,减少

=============================================

下载:

PPA
https://launchpad.net/~coolwanglu/+archive/scanmem
我只在64bit Karmic下进行了测试,其他环境如果不能正常使用请告知,谢谢

SVN
svn checkout http://scanmem.googlecode.com/svn/trunk/ scanmem

主页:
http://code.google.com/p/scanmem/
下载时注意选择0.09版本

运行需要python和python-gtk2, 编译需要libreadline(大多数发行版应该都默认安装吧)

=============================================

GameConqueror的BUG或者不恰当的使用会导致程序崩溃,请务必注意备份数据,资料等等。

安装后应该在“游戏”类别里出现菜单项,也可以直接运行gameconqueror(请在终端内运行,见下)

查看Value的悬停提示(tooltip)可以了解各种搜索语法,参考了金山游侠

至于那个烦人的终端窗口,现在只能在这里看到搜索进度和出错信息。我之前主要是实现scanmem的各种功能,界面改进则是下个版本的目标

=============================================

未来考虑实现的功能:

- 界面改进(搜索进度条,出错提示,用户交互等等)
- 指针搜索
- 可选的浮点数取整方式
- 十六进制内存查看/编辑器

不会实现的功能:

- 变速 (类似变速齿轮,这个不是不想写,而是不会写,有谁能教教我?)
- 反汇编器

欢迎使用,感谢反馈。

GameConqueror 0.09 -- Linux Game Hacking Tool

If you are a game hacker
If you've been looking for a `CheatEngine for Linux`

Then you can't miss this.

==============================================


GameConqueror is a game hacking tool for linux, it's written in PyGTK and uses scanmem as its backend.

It's supposed to be with most useful features of CheatEngine for Linux.

Currently, I've implemented almost everything about scanning, involving variant data types and scan types:

Data Types: int{8/16/32/64}, float{32/64}, unknown type(int or float) and unknown width(will try each of them), byte array and string
Scan Types: equal, greater, less, changed, unchanged, increased(by), decreased(by)

This should be enough for most cases, so I decided to release it at the current status.

=============================================

Here's how you can get it

PPA (for Ubuntu users)
https://launchpad.net/~coolwanglu/+archive/scanmem
(I've not test it in 32bit environments or Jaunty, do please inform me if it doesn't work)

SVN
svn checkout http://scanmem.googlecode.com/svn/trunk/ scanmem

Homepage:
http://code.google.com/p/scanmem/
make sure you selected the correct version `0.09`

You'll need python and python-gtk to run it, and to build it from source code, you'll need libreadline (this should have been installed for most of you)

=============================================

NOTE THAT GAMECONQUEROR MAY CRASH YOUR PROGRAM DUE TO BUGS OR IMPROPERLY USAGE, DO BACKUP YOUR PROGRESS BEFOREHAND.

To use it, actually I've created a menu item, which could be found in the 'Games' category, or you can run it by executing `gameconqueror`, and please do this in a terminal (see below)

Read the tooltip of the label 'Value' to get familiar with the syntax

About the annoying terminal window, now this is the only place where you can see the progress of scanning, and the error message if something goes wrong. This terrible thing is basically because I've mainly focused on the features of scanmem so far, and I'll fix this in the next version.

=============================================

What will be added in the next (or maybe future) version:

- better ui (progress bar, error message, user interaction, etc...)
- search for pointers
- optional float rounding method
- memory viewer/editor


and what will not be added
- speed hack (I've no idea about how to implement this in Linux, can anyone tell me plz?)
- disassembler
- many other `too powerful` features in CheatEngine


any feedbacks will be appreciated.


2010-01-04

autotools, deb 和 PPA 不完全攻略

最近在给自己的GameConqueror折腾 PPA, 那少不了折腾标题里的三样东西。下决心看了一遍三个东西的文档,整理如下

链接
autotools:
AutoconfAutomake

deb packaging:
Debian New Maintainers' Guide
Ubuntu Packaging Guide
Building Package for PPA

PPA stuff
PPA Overview
Uploading


那么一个一个说:
注意: 本篇系个人总结而非教程,如有疑问请参阅上述链接。


1. AUTOTOOLS
autotools 的精髓是让开发者免于手写繁琐的Makefile,同时又让最后生成的源码包符合GNU的一套标准。然而autotools本身也很难用。。。入门门槛比较高。当然难用是相对的,掌握了基本要领就可以了

需要手写的文件一般是一个configure.ac和若干个Makefile.am, ac和am分别是autoconf和automake的缩写

configure.ac定义了源码包整体信息,如名称,版本,编译环境等,最后根据configure.ac输出configure,而configure可以判断编译环境是否满足需要,这就是著名的./configure && make 的前一半

Makefile.am则是Makefile的另一种格式,由于绝大多数C/C++或一些其他语言的程序编译,打包,安装等等都是同一模式,所以才有了automake,Makefile.am的作用是决定程序的编译方式,还有各个文件的类型,是否打包,安装位置等等,这些由automake生成许多Makefile.in一起打包,等到编译时./configure会把Makefile.in再变成Makefile

关于configure.ac, 最开始可以用autoscan生成一个模板,自己慢慢改,有许多宏,都可以在autoconf的网页上查到

一般(我看到的)分为两个部分,前一半检查编译环境,后一半把检查的结果输出,一般就是进行宏替换等等。

检查编译环境,一般无非是编译器(是否存在,编译选项,特性支持),库(是否存在,版本),条件编译(是否启用的某个功能,或其他编译时指定的参数),这一部分去查AC_CHECK*,AM_CONDITIONAL这些宏好了,很好用

第二部分是宏替换,相关的宏是AC_CONFIG_FILES和AC_OUTPUT。Makefile.in是自动生成的,也会自动被替换,不用管它。我遇到的情况是需要写一个脚本,里面有个路径是安装路径,这样的话,我需要写一个script.in:

DATAPATH=@INSTALLPATH@

# do anything with $DATAPATH

然后在configure.ac里加上AC_CONFIG_FILES([script])

以及AS_AC_EXPAND(INSTALLPATH, "some path")

这样到时候configure的时候就会生成一个script,里面是DATAPATH=some path

其中AS_AC_EXPAND不是autotools里的宏,我是从ubuntu-tweak包里抄来的,再往上就找不到确切出处了

把这段放configure.ac里就好了
dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR)
dnl
dnl example
dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local

AC_DEFUN([AS_AC_EXPAND],
[
EXP_VAR=[$1]
FROM_VAR=[$2]

dnl first expand prefix and exec_prefix if necessary
prefix_save=$prefix
exec_prefix_save=$exec_prefix

dnl if no prefix given, then use /usr/local, the default prefix
if test "x$prefix" = "xNONE"; then
prefix=$ac_default_prefix
fi
dnl if no exec_prefix given, then use prefix
if test "x$exec_prefix" = "xNONE"; then
exec_prefix=$prefix
fi

full_var="$FROM_VAR"
dnl loop until it doesn't change anymore
while true; do
new_full_var="`eval echo $full_var`"
if test "x$new_full_var" = "x$full_var"; then break; fi
full_var=$new_full_var
done

dnl clean up
full_var=$new_full_var
AC_SUBST([$1], "$full_var")

dnl restore prefix and exec_prefix
prefix=$prefix_save
exec_prefix=$exec_prefix_save
])

另外需要看看AC_SUBST这个宏以及一些标准路径定义,如datadir等等

那么configure.ac基本就这么回事了,下面是Makefile.am

网上的很多教程上来就说“对于一个简单的hello程序,我们可以写如此一个Makefile.am”,但是再往下就没有了。但是像我每次看到Makefile.am里面的bin_PROGRAMS, xxx_SOURCES等等,我会想bin是啥玩意, PROGRAMS又是啥 -- 基本没查到,只能看文档。

实际是这样的
bin_PROGRAMS: bin是安装路径,即${prefix}/bin, 而prefix就是configure时指定的那个--prefix
_PROGRAMS: 是autotools里预设的宏,好比说,我想到了LaTeX里的\documentclass,基本就是一回事,其他还有_SCRIPTS, _DATA, _LIBRARIES,具体去查文档

如果定义了bin_PROGRAMS = scanmem # scanmem就是我正在搞的那个包
那么下面就会有scanmem_SOURCES = xxx.c yyy.c 这种,scanmem_XXX就是指定scanmem的具体内容了,除了_SOURCES还有_CFLAGS等等

类似的例子是dist_doc_DATA = AAA BBB, 这样 AAA BBB 会被安装到 docdir 里去,这也是个标准定义,一般是${prefix}/share/doc/$PACKAGE。 dist_则是前缀,为了将来把AAA BBB一起打包, make dist 默认是不把_DATA的内容放到包里

另外你可以可以自己写scanmem_PROGRAMS这种,但是要注意定义scanmemdir,就是对应的安装目录

还有一些:
EXTRA_DIST: 这种是强制把某些内容放到源码包里
SUBDIRS: 表示make的时候需要光顾的目录,如果 SUBDIRS = aaa . bbb, 那么就分别到aaa, 当前目录和bbb去make一番

常用的就这些把,记得把每个目录的Makefile.am都加到configure.ac里去,如
AC_CONFIG_FILES([Makefile
src/Makefile
xxx/Makefile
])

所有东西都搞完以后打个autoreconf (如果缺文件可能需要加--install)就齐活了,这时候已经可以./configure && make 了,如果想打包就make dist,这时候才终于发现了autotools的好用。。。

关于autotools的感想就这么多,总之还是看文档最有效,说的已经很清楚了。

2. DEB 打包
首先需要装一堆脚本,我也忘了有哪些了
主要需要的是debian这个目录,里面必要的文件是control copyright changelog rules这几个文件,如果没有的话可以用dh_make -e 这个命令生成一些基本的,但是我还是建议对照着一个现有的deb包看

control最简单了,照猫画虎就好了,第一大段是源码包信息,下面若干段是deb包信息,这个源码包最后打出几个deb包来就写几段

changelog需要一定格式,用dch命令,非常好用

dch:在最新的changelog entry加一段文字
dch -i: 新建一个changeleog entry,版本修订号加1
dch -v :新建一个changelog entry, 指定版本号为version

另外,最后的deb包的版本是由changelog最新一项决定的

rules:这个是打包用的Makefile,对于简单的包,可以用cdbs,虽然一听新名词显得很麻烦,但是实际上只需要如下几行

#!/usr/bin/make -f

include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk

DEB_CONFIGURE_EXTRA_FLAGS := --enable-gui

就行了,最下面是自定义的configure参数,还有一些其他的类似的变量

另外务必在control的Build-Depends里加上cdbs

copyright:最“没用”也是最难搞的,说明这个包是谁整的,原来作者是谁,原来的文件分别的版权和协议(由于我的包是多作者多协议,所以很麻烦),最后是这个包的协议。 这个文件对照着说明慢慢整好了。。。

这些文件都搞定以后,用debuild或者dpkg-buildpackage就好了

具体操作是这样:

首先搞来源码包,如scanmem-0.09.tar.gz,把它改名为scanmem_0.09.orig.tar.gz,注意包和版本号中间的-改为_,另外就是加个.orig
然后解压,进入scanmem-0.09目录,建立debian目录,写需要的东西。(可以用dh_make或者copy一份)
然后debuild,等会儿就好了

其他说明
1.debuild是编译成.dsc .orig.tar.gz .diff.gz这三个文件,还有个.changes 而dpkg-buildpackages则是最终搞若干个.deb

2.我的另一个需求是一个源码包搞出两个deb package出来,这个我搜了好久,现在似乎唯一可用的资源是ubuntu packaing guide以及这个链接http://www.miriamruiz.es/weblog/?p=42,我再整理一下,大致是这个样子

我现在是想编译两个包,分别是scanmem和gameconqueror,那么control文件里自然要分别写一套信息,而另一方面在debian目录里建立scanmem.install gameconqueror.install两个文件,分别是需要的文件列表,可以用通配符,例如
#scanmem.install
usr/bin/scanmem

#gameconqueror.install
usr/bin/gameconqueror
usr/share/gameconqueror/*

这样就可以了。

另外就是,默认rules是把需要的内容安装到debian/tmp/下,而如果用dh_make按照single binary的设置输出,rules文件会设成安装到debian/scanmem,需要改成tmp,否则报错

由于我主要是给PPA打包,所以用到的是debuild, dpkg-buildpackage以前自己编译内核是用过

3.我看了Debian的打包说明,发现了svn-buildpackage这个好东西,适合我这种直接在svn里搞的人。

直接在svn里建立debian目录和相关文件,然后svn-buildpackage --svn-builder=debuild -S -sa -k就搞定了,最后的东西到../build-area里去找,另外--svn-builder后面这堆参数是为PPA用的

3. PPA
ubuntu 社区的PPA确实是个好东西,装了很多PPA很是羡慕,现在也终于有一个自己的PPA了

激活PPA的大致流程是:

注册Launchpad帐号
建立一个PPA,设置名称,说明等等
创建一个自己的OpenPGP密钥,发布到Ubuntu Key Server, 再导入到Launchpad
签署Ubuntu Codes of Conduct,就是拿自己的私钥加密一个文件再上传

所有步骤在上面所述的PPA Overview链接都有说明,界面简介,高效,甚至有趣,我在操作过程中笑了好几次。倒不是多幽默,主要是确实好用,也是第一次实际操作公钥私钥这种东西。

然后就是上传了,按照Uploading Guide 慢慢来就好了。如果编译没问题,这一步很简单。只是注意要导入自己的公钥,以及签署Ubuntu Codes of Conduct。



基本就这些了,再一次跟开源世界亲密接触,真爽!