使用WEBrick创建代理服务器并修改会话内容

还是出于自动化玩网页游戏的需求,希望可以截获浏览器接收到的数据并修改,那样可以改变网页游戏在本地的表现;或者截获浏览器发往服务器端的数据,那样可以直接修正服务器的数据,达到一些永久性的改变(作弊什么的太不好了)。

使用Fiddler2可以方便地测试一些想法的可行性:

  1. 配置浏览器使用 Fiddler2 代理
  2. 菜单 Rules -> Automatic Breakpoints -> Before Requests
  3. 浏览器发起请求的时候在右侧的 Inspectors 里面修改 Request 的相关参数 [Request]
  4. 点击下方的 Break on response,Fiddler会发起请求,并暂停在接收到数据的时候
  5. 修改接收到的数据(gzip的数据可以点一下上方的黄条先行解压),点 Run to completion [Response]

Fiddler2本身支持JScript.NE[......]

继续阅读

Flash SWF文件的简单加壳与解壳

最近玩一个网页游戏停不了手,就想写个脚本把游戏自动化什么的,那样玩一会马上就没意思了,自然就停掉了。

拿到游戏的swf文件,挑准名字看起来像是包含核心逻辑的一个,上反编译工具,800K的swf文件只弄出来20K的东西。以前没碰过这种情况,一时间有些束手。查看仅有的一点点代码,发现某个初始化方法里面直接引用了一个几乎为空的类encrypt_swf,而另一部分逻辑还再次去加载了这个类:


public class entrypt_swf extends mx.core.ByteArrayAsset
{
public function entrypt_swf()
{
return;
}
}
public class encrypt extends Sprite {[......]

继续阅读

Scala中的Traversable特质提供的方法分类

Traversable特质是处于Scala中集合类体系中最顶端的特质,它提供唯一的一个抽象方法foreach:

def foreach[U](f: Elem => U)

混入了Traversable特质的集合类只需要实现这个foreach方法,即可继承和使用Traversable特质中的其他具体方法。

foreach方法用于遍历集合中的每一个元素,对其应用传入的操作f。f的类型是 (Elem => U),即接受一个Elem类型的变量,返回一个U类型结果的方法。其中Elem是集合类中元素的类型,而U类型大多无关紧要。执行foreach主要为的是调用f所产生的副作用(打印、赋值等),而最终结果会被foreach直接丢弃。

Traversable特质中定义了许多具体方法(部分方法依赖于foreach实现)。由于Traversable特质位于集合类体系[......]

继续阅读

使用Scala的Continuations实现用yield生成迭代器

Rich Dougherty在StackOverflow的这个问题的回答里面使用Scala的continuations实现了一个简单的类似于C#中yield return的迭代器生成环境。

首先需要的是一个转换continuations链(通用的,不一定由shift/reset生成)为相应的迭代器,将Rich Dougherty的代码稍加修改即:


sealed trait Iteration[+R]
case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R]
case object Done extends Iteration[Nothing]

object Iteration {
def trampoline[R](body: =&gt[......]

继续阅读

Scala中的Continuations(续)

Scala中的shift/reset实现的Continuation是编译器的一种语法扩展,这种扩展不仅仅是语法糖层面的内容。

首先,Scala使用一个Shift类来存储shift块的程序逻辑。Shift类本身实现了map和flatMap方法,这样,它可以方便地用于Scala原生支持的for…yield…语法糖。Shift类的泛型参数A,C有+标记,意味着其支持协变,而B则支持逆变。


class Shift[+A, -B, +C](val fun: (A => B) => C) {
def map[A1](f: (A => A1)): Shift[A1, B, C] = {
new Shift((d: (A1 => B)) =>
fun((x: A) => d(f(x))))
}[......]

继续阅读

Scala中的Continuations

Continuation是一种特殊的过程(函数),它封装了从当前点开始的全部计算过程,通过传入当前表达式的值作为参数从而完成剩余的计算。在一般的编程语言里可以使用函数指针(或同等对象)实现类似的行为。比如考虑如下的两个Scala方法及其调用:

def foo(x: Int): Int = {
  x + 1
}
def fooContinuted(x: Int, continuation: (Int => Unit)) {
  continuation(x + 1)
}
val ret = foo(2)
println(ret)
fooContinuted(2, v => println(v))

Scala 2.8中引入了定界的(Delimited) Continuations特性,可以使用scala.util.[......]

继续阅读

非递归排列算法(Permutation Generation)

将长为n的一个序列a_1, a_2, …, a_n,进行全排列,一共有n*(n-1)*…*2*1=n!种排列方案。有一种简单的递归算法实现全排列,从给定列表中依次选出一个元素(有n种方法)作为结果的第一个元素,然后对剩余的n-1个元素做全排列,实现如下:


// var arr = new [] { 1, 2, 3 };
// Permutation(arr, arr.Length – 1, list => Console.WriteLine(string.Join(", ", list)));
static void PermutationRecursive<T>(IList<T> list, int n, Action<IList<T>> action) {
if ([......]

继续阅读

NIM(1)一排石头的游戏之扩展问题解法

《编程之美》一书中1.11章节介绍了NIM游戏的取胜问题。N块石头排成一行,每块石头有各自固定的位置。两个玩家依次取石头,每个玩家每次可以取其中任意一块石头,或相邻的两块石头,石头在游戏过程中不能移位(即编号不会改变),最后能将剩下的石头一次取光的玩家获胜。在这样的规则下,先取的玩家可以在第一步取走最中间的一个(总数为奇数时)或者两个(总数为偶数时)石头,然后后续过程中总取与对手取走的石头对称位置的相同数目的石头。因而先取者有必胜策略。

文末的扩展问题部分提出一个问题:若规定最后取光石头的人输,又该如何应对呢?

网上似乎也没有这个问题的明确解法,有的给出过证明石头总数3N+1时无法找到必胜策略其余的则可以,但是可以看出证明过程中有明显的漏洞,而且证明的这个3N+1的命题本来就是错误的……

定义S为石头摆放的一个格局,格局标识石头目前的连续区段的状态以及每个连续[......]

继续阅读

Python脚本中的字符编码处理

平时用Python不多,偶尔拿起来用的时候就被中文处理给绊到。看过了了解了隔段时间不用难免又忘了,下次再用的时候又要重新整。把现在了解到的写下来,下次需要的时候好参考参考。

Python默认使用ASCII编码来解析脚本文件。当脚本正文中有非ASCII字符时候,Python仍然会尝试使用ASCII编码来解析这些字符,显然很可能会出现错误:

#! /usr/bin/env python

# 你好
print "你好"

File “test.py”, line 4
SyntaxError: Non-ASCII character ‘\xe6′ in file test.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263[......]

继续阅读

atoi函数的实现

这好像是经常看到的一个程序猿面试题,考官问,请你实现一个C函数,来将一个数字字符串转换成其整数形式。如果简单地按照取数字,加10倍目前所得到的数这样的循环做下去,可以得到一个基本可用的结果。考官接下来问:

  • 你的实现可以处理负数么?

负数还好处理,在方法初始部分添上符号判断的逻辑再按正数的逻辑进行剩余部分的转换,在返回结果前依据正负号将结果符号纠正一下就可以了。

  • 你的实现在最大的整数和最小整数边界上能不能正常工作?

引入负数之后,第二个问题来了,第二个问题应该主要是问在最小负数这个边界上面能否正常工作。这是因为普通的整数表示里面,可以表示的负数个数要比可以表示的正数个数多1。最小负数的绝对值比最大正数大1。这样,如果简单地按照正数的处理逻辑的话,只能够得到最大的那个正数,置换负号之后便得不到最小的负数。但注意到最大正整数和最小负整数之间的所有数都是可以使用整型值正常表示的(不[......]

继续阅读