Outlook 2010 VBA Debug.Print 和 DateToString

一.在Outlook中可以用 Debug.Pring + 内容 直接输出运行结果。不过需要用 ctrl+G 打开Immediate Window

二.下面的程序可以用来将一个 Date 类型转换为 String

Sub DateToString()
Dim d As Date
d = Now

Debug.Print (d)

Dim s As String

s = Format([d], “yyyymmddhhnnss”)

Debug.Print (s)
End Sub

format具体用法可以参考 http://msdn.microsoft.com/en-us/library/gg251755.aspx

vbadatetostring

机器码对汇编指令的转换工具

偶然间发现 Win7 64位并不提供debug.exe工具,这给反汇编机器码带来一些困难(特别是公司只容许安装正版软件)。在网上搜索发现一个很好用的反汇编引擎 BeaEngine。利用这个引擎编写了一个简单的命令行工具用来实现机器码到汇编指令的转换。

第一步:给定反汇编默认的地址,这对于跳转指令特别重要.按”u”之后输入地址;如果不需要,直接回车即可

第二步:输入欲编译的机器码,回车后即开始转换为汇编指令

特别情况:

1.有可能出现无法识别的指令

2.0×0087 和 0x87 0x00 这样的机器码是等价的,但是0x87 并不等于 0x0087。

3.默认的反编译指令集是32位的,通过修改源程序可以变成8086或者x64的

This is a utility which can covert machine code to assemble code (disassemble). It is based on a disassemble engine which named BeaEngine.
Both source code and executable files are in the package. You can rebuild it with Delphi10.

step1:input a virtual EIP which will be set as the beginning address of the assemble code

step2:input the machine code in Hex. It will be transferred to assemble code after pressing Enter

Note:

1. Some hex number may not be recognized

2. The number ’00’ is meaningful as the prefix of a Hex. Ex. 0x0087 will be recognized as 0x87 and 0x00. It’s different with 0x87.

3. Default instruction is 32 Bits. It can be switched to 8086 or x64 by modifying and rebuilding the source code.

m2a

Delphi 调用BeaEngine 反汇编的例子 (DLL版)

/////////////////////////////////////////////////////////////////////////
//
// Delphi 调用BeaEngine 反汇编的例子
// 这是使用 DLL 的版本,Release程序的时候需要将 BeaEngine.dll一同发布
//
// By Zoologist
// www.lab-z.com
// 2013-02-21
/////////////////////////////////////////////////////////////////////////
program BeaConsoleTest;

{$APPTYPE CONSOLE}

uses
SysUtils,BeaEngineDelphi32;

procedure DisasmCode;
var
MyDisasm:TDISASM;
i,len:integer;
begin
// ======== Init the TDisasm structure (important !)
FillChar(MyDisasm,sizeof(TDISASM),0);

// ======== Init EIP
MyDisasm.EIP:=Int64(@DisasmCode);
MyDisasm.Archi:=0;
MyDisasm.Options:=NoTabulation + MasmSyntax;

// ======== Loop for Disasm
for i:=1 to 20 do
begin
len:=Disasm(MyDisasm);
Writeln(IntToHex(MyDisasm.EIP,2)+’ ‘+MyDisasm.CompleteInstr);
MyDisasm.EIP:=MyDisasm.EIP+len;
end;
end;

begin
Writeln(‘This is a BeaEngine Test program for delphi.’);
DisasmCode;
Writeln(‘Press Enter to exit…’);
Readln;
end.

特别的需要修改 BeaEngineDelphi32.pas 打开使用 DLL 反编译方式

// ====================================================================
// [+] BranchTaken,BranchNotTaken added in TPREFIXINFO v3.1.0
unit BeaEngineDelphi32;
// ====================================================================
// Default link type is static lib
// comment below line to switch link with DLL
// ====================================================================
{$DEFINE USEDLL}
// ====================================================================
// Copyright 2006-2009, BeatriX
// File coded by BeatriX

编译之后的EXE需要连同 DLL 一起发布才能正常工作。下面是完整的例子

Bea1

Delphi 调用BeaEngine 反汇编的例子 (OBJ加入编译)

/////////////////////////////////////////////////////////////////////////
//
// Delphi 调用BeaEngine 反汇编的例子
// 这是直接和Obj进行链接的例子,Release程序的时候直接发布EXE文件即可
//
// By Zoologist
// www.lab-z.com
// 2013-02-22
/////////////////////////////////////////////////////////////////////////

program BeaConsoleTest;

{$APPTYPE CONSOLE}

uses
SysUtils,BeaEngineDelphi32;

procedure DisasmCode;
var
MyDisasm:TDISASM;
i,len:integer;
begin
// ======== Init the TDisasm structure (important !)
FillChar(MyDisasm,sizeof(TDISASM),0);

// ======== Init EIP
MyDisasm.EIP:=Int64(@DisasmCode);
MyDisasm.Archi:=0;
MyDisasm.Options:=NoTabulation + MasmSyntax;

// ======== Loop for Disasm
for i:=1 to 20 do
begin
len:=Disasm(MyDisasm);
Writeln(IntToHex(MyDisasm.EIP,2)+’ ‘+MyDisasm.CompleteInstr);
MyDisasm.EIP:=MyDisasm.EIP+len;
end;
end;

begin
Writeln(‘This is a BeaEngine Test program for delphi.’);
DisasmCode;
Writeln(‘Press Enter to exit…’);
Readln;
end.

使用原来的 BeaEngineDelphi32.pas 无法编译(我用 Delphi 2006),需要加入一些代码,下面斜体显示

implementation
{$IFNDEF USEDLL}
{$L BeaEngineLib.obj}

function strcmp(dest, src: PAnsiChar): DWORD;cdecl;
begin
Result := SysUtils.CompareStr(dest, src);
end;

function strcpy(dest, src: PAnsiChar): PAnsiChar;cdecl;
begin
Result := SysUtils.StrCopy(dest, src);
end;

更具体的修改,请参考附件。

Bea2

介绍一个反汇编引擎 BeaEngine

介绍一个反编译引擎 BeaEngine

来自 http://www.beaengine.org/ 是一个免费的反汇编引擎,能够支持多种语言,比如:Python VC MASM32 Delphi 等等

主要函数

1.Disasm 函数

语法:

int Disasm(
pDisasmStruc pMonDisasm
);

参数:

pMonDisasm

[out] 返回指向 DisasmStruc 结构体的指针

函数返回值:

返回值有3种可能。如果遇到无法识别的opcode,返回 UNKNOWN_OPCODE (-1);如果读取出界(也就是读取超过安全区范围),那么返回OUT_OF_RANGE (0);其余情况返回指令长度。

——————————————————————————–
2.BeaEngineVersion 函数

返回当前引擎的版本信息

语法:

char* BeaEngineVersion(void);

返回值:

返回一个指向以0结尾的字符串,其中是当前版本信息。

——————————————————————————–
2.BeaEngineVersion 函数

返回当前引擎的修订版信息。(我不清楚 version和revision的差别.也许是因为我不用SVN之类的版本控制软件吧:)

The BeaEngineRevision function allows you to retrieve the current revision of the engine. Revisions come from our google SVN and can be considered like indicators about last bug fixes.

语法

char* BeaEngineRevision(void);Return

返回一个指向以0结尾的字符串,其中是当前修订版信息。

一些用到的结构体

_Disasm = packed record
EIP : longint; //引擎开始Decode的位置
VirtualAddr : int64; //反编译起始处的虚拟IP
SecurityBlock : longint; //为了防止在反编译过程中出现溢出,需要多指定一些字节作为缓冲
CompleteInstr : array[0..(INSTRUCT_LENGTH)-1] of AnsiChar; //输出的完整指令
Archi : longint; //指定指令集的类型
Options : int64; //定义一些指令显示的方法
Instruction : TINSTRTYPE;
Argument1 : TARGTYPE;
Argument2 : TARGTYPE;
Argument3 : TARGTYPE;
Prefix : TPREFIXINFO;
Reserved_ : array[0..39] of longint;
end;
TDISASM = _Disasm;
PDISASM = ^_Disasm;
LPDISASM = ^_Disasm;

TINSTRTYPE = packed record
Category : longint; //指令集的家族,比如:MMX
Opcode : longint; //OPcode
Mnemonic : array[0..15] of AnsiChar; //助记符
BranchType : longint; //如果是分支指令,那么给出跳转条件,例如:无条件跳转
Flags : TEFLStruct; //对 EFLAGS 的影响
AddrValue : int64; //如果解码之后的指令是一个分支指令,并且目标地址能够计算出(非运行期才能计算出来的),例如: jmp eax 会让这个位置为0
Immediat : int64; //指令中使用的常数
ImplicitModifiedRegs : longint; //该指令影响的寄存器
end;

TARGTYPE = packed record
ArgMnemonic : array[0..31] of AnsiChar; //返回ASCII形式的参数
ArgType : longint; //返回参数类型
ArgSize : longint; //返回参数大小
ArgPosition : longint; //参数类型为 REGISTER_TYPE 并且只使用了8位
//寄存器(Legacy模式)。ArgPosition=1 表示使用的是
//AH CH BH或者DH,反之为 AL BL CL 或者DL
AccessMode : longint; //表明参数是否为可修改(WRITE=0x02)或者(READ=0x01)
Memory : TMEMORYTYPE; //返回寻址模式
SegmentReg : longint; //寻址使用的段寄存器
end;

下载:

32位 beaengine-win32

64位 beaengine-win64

帮助文档(为了防止某天,这个网站被墙) beahelp

bea

VC 中输出当前运行的文件和所处的行数以及所在函数名称的方法

通过下面的例子,可以到到 VC 可以在运行过程中输出当前运行的文件和所处的行数以及所在函数名称。如果需要追踪你程序的流程,并且能够获得运行期的Log文件,这将是一个很好的追踪方法

#include “stdafx.h”

void foo()
{
printf(“Run in file %s, line %d Function %s\n”, __FILE__, __LINE__, __FUNCDNAME__);
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
printf(“This is a simple demo to show how to show Filename Line Number and Function Name \n”);
printf(” Powered by www.lab-z.com Z.t \n”);
printf(“Run in file %s, line %d Function %s\n”, __FILE__, __LINE__, __FUNCDNAME__);
foo();
getchar();
return 0;
}

运行结果:

1

注意到其中的文件名给出的是相对路径,可以通过下面的位置设置为完整路径

2

之后的运行结果

Untitled

其中使用的 __FILE__ 和 __LINE__ 是c语言标准中定义的

下面文字来源于 http://topic.okbase.net/200510/2005102110/2170344.html

看ISO14882
6.10.8 Predefined macro names
1 The following macro names148) shall be defined by the implementation:
_ _DATE_ _ The date of translation of the preprocessing translation unit: a character
string literal of the form “Mmm dd yyyy”, where the names of the
months are the same as those generated by the asctime function, and the
first character of dd is a space character if the value is less than 10. If the
date of translation is not available, an implementation-defined valid date
shall be supplied.
_ _FILE_ _ The presumed name of the current source file (a character string literal).149)
_ _LINE_ _ The presumed line number (within the current source file) of the current
source line (an integer constant).149)
_ _STDC_ _ The integer constant 1, intended to indicate a conforming implementation.
_ _STDC_HOSTED_ _ The integer constant 1 if the implementation is a hosted
implementation or the integer constant 0 if it is not.
_ _STDC_VERSION_ _ The integer constant 199901L.150)
_ _TIME_ _ The time of translation of the preprocessing translation unit: a character
string literal of the form “hh:mm:ss” as in the time generated by the
asctime function. If the time of translation is not available, an
implementation-defined valid time shall be supplied.
2 The following macro names are conditionally defined by the implementation:
_ _STDC_IEC_559_ _ The integer constant 1, intended to indicate conformance to the
specifications in annex F (IEC 60559 floating-point arithmetic).
148) See ‘‘future language directions’’ (6.11.9).
149) The presumed source file name and line number can be changed by the #line directive.
150) This macro was not specified in ISO/IEC 9899:1990 and was specified as 199409L in
ISO/IEC 9899/AMD1:1995. The intention is that this will remain an integer constant of type long
int that is increased with each revision of this International Standard.
160 Language §6.10.8
©ISO/IEC ISO/IEC 9899:1999 (E)
_ _STDC_IEC_559_COMPLEX_ _ The integer constant 1, intended to indicate
adherence to the specifications in informative annex G (IEC 60559
compatible complex arithmetic).
_ _STDC_ISO_10646_ _ An integer constant of the form yyyymmL (for example,
199712L), intended to indicate that values of type wchar_t are the
coded representations of the characters defined by ISO/IEC 10646, along
with all amendments and technical corrigenda as of the specified year and
month.
3 The values of the predefined macros (except for _ _FILE_ _ and _ _LINE_ _) remain
constant throughout the translation unit.
4 None of these macro names, nor the identifier defined, shall be the subject of a
#define or a #undef preprocessing directive. Any other predefined macro names
shall begin with a leading underscore followed by an uppercase letter or a second
underscore.
5 The implementation shall not predefine the macro _ _cplusplus, nor shall it define it
in any standard header.
Forward references: the asctime function (7.23.3.1), standard headers (7.1.2).

__FUNCDNAME__ 是 VC 自定义的
介绍在 http://msdn.microsoft.com/en-us/library/b0084kay(VS.71).aspx

__FUNCDNAME__ Valid only within a function and returns the decorated name of the enclosing
function (as a string). __FUNCDNAME__ is not expanded if you use the /EP or /P compiler option.

给WordPress加上文章阅读次数功能

安装完WordPress后(WordPress 3.5.1),默认已经有 WP-PostViews 插件,可以直接在“插件”–>;“已安装的插件”中看到。确定这个功能是启用之后,可以在“外观”–>;当前主题的“小工具”中配置“第一小工具区”中 Views。这样就能够在边栏显示阅读数量最多的文章。具体的配置方法在网上都能搜索到,这里不再重复。重点说一下 Twenty Ten 这个主题如何显示每篇文章的阅读数量。非常抱歉的是这个主题和其他网上教程中讲述的都不同,无法找到给出的“主循环”。因此,选择插入在 Single.php 文件中(可以从“仪表盘”–>“外观”–>“编辑”直接选择编辑文件)。注意要加入到下面指定的位置中

之后就是这样的效果了………

参考如下文章:

http://wordpress.org.cn/thread-143947-2-1.html

更新完成

用了一个春节的时间,将原来手工页面编写的网页更换为了 WordPress 界面的。总共花费了大约100多个小时。期间的感悟是:360浏览器真的不好用,不知道为什么家里的电脑强制安装了一个360浏览器,我刚开始也没有在意,用着它就开始了WP之旅,不成想几乎上传几次附件之后就要崩溃一次,整个浏览器都没有反应的。后来的某一天,去给一个朋友检修电脑,她也提到浏览器不正常的问题而正好也是360浏览器,始悟一定是它捣鬼的……果真更新之后正常多了。不太清楚,360使用的是IE内核,但是为什么把浏览器搞的如此之不好用?

另外一个感悟是,Wordpress的安装和使用比想象中的简单多了,功能也是异乎寻常的强大。现在可以方便的显示阅读最多的文章,也可以方便的让别人订阅我的RSS。看起来引入新技术,引入新方法能够提高效率才是最顺应潮流的做法。

最后放上两张很久之前CPascal的网站截图,聊作纪念。