byrefpython
⑴ python怎么修改某个内存地址的数据
使用ctypes模块调用WriteProcessMemory函数,在创建程序进程后,就可以修改该程序指定内存地址。WriteProcessMemory的函数原型如下所示。
BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T* lpNumberOfBytesWritten
);
其参数含义如下。
· hProcess:要写内存的进程句柄。
· lpBaseAddress:要写的内存起始地址。
· lpBuffer:写入值的地址。
· nSize:写入值的大小。
· lpNumberOfBytesWritten :实际写入的大小。
python代码示例如下:
fromctypesimport*
#定义_PROCESS_INFORMATION结构体
class_PROCESS_INFORMATION(Structure):
_fields_=[('hProcess',c_void_p),
('hThread',c_void_p),
('dwProcessId',c_ulong),
('dwThreadId',c_ulong)]
#定义_STARTUPINFO结构体
class_STARTUPINFO(Structure):
_fields_=[('cb',c_ulong),
('lpReserved',c_char_p),
('lpDesktop',c_char_p),
('lpTitle',c_char_p),
('dwX',c_ulong),
('dwY',c_ulong),
('dwXSize',c_ulong),
('dwYSize',c_ulong),
('dwXCountChars',c_ulong),
('dwYCountChars',c_ulong),
('dwFillAttribute',c_ulong),
('dwFlags',c_ulong),
('wShowWindow',c_ushort),
('cbReserved2',c_ushort),
('lpReserved2',c_char_p),
('hStdInput',c_ulong),
('hStdOutput',c_ulong),
('hStdError',c_ulong)]
NORMAL_PRIORITY_CLASS=0x00000020#定义NORMAL_PRIORITY_CLASS
kernel32=windll.LoadLibrary("kernel32.dll")#加载kernel32.dll
CreateProcess=kernel32.CreateProcessA#获得CreateProcess函数地址
ReadProcessMemory=kernel32.ReadProcessMemory#获得ReadProcessMemory函数地址
WriteProcessMemory=kernel32.WriteProcessMemory#获得WriteProcessMemory函数地址
TerminateProcess=kernel32.TerminateProcess
#声明结构体
ProcessInfo=_PROCESS_INFORMATION()
StartupInfo=_STARTUPINFO()
file='ModifyMe.exe'#要进行修改的文件
address=0x0040103c#要修改的内存地址
buffer=c_char_p("_")#缓冲区地址
bytesRead=c_ulong(0)#读入的字节数
bufferSize=len(buffer.value)#缓冲区大小
#创建进程
ifCreateProcess(file,0,0,0,0,NORMAL_PRIORITY_CLASS,0,0,byref(StartupInfo),byref(ProcessInfo)):
#读取要修改的内存地址,以判断是否是要修改的文件
ifReadProcessMemory(ProcessInfo.hProcess,address,buffer,bufferSize,byref(bytesRead)):
ifbuffer.value=='x74':
buffer.value='x75'#修改缓冲区内的值,将其写入内存
#修改内存
ifWriteProcessMemory(ProcessInfo.hProcess,address,buffer,bufferSize,byref(bytesRead)):
print'成功改写内存!'
else:
print'写内存错误!'
else:
print'打开了错误的文件!'
TerminateProcess(ProcessInfo.hProcess,0)#如果不是要修改的文件,则终止进程
else:
print'读内存错误!'
else:
print'不能创建进程!'
⑵ python怎么调用c的动态链接库
Python调用C/C++动态链接库的需求
在自动化测试过程中,难免会遇到语言混合使用的情况,这不,我们也遇到了。初步决定采用Robot Framework作为自动化测试框架后,其支持Java和Python,而Python作为主流的语言,怎么能放弃使用它的机会^_^。 然而产品采用是古老90年代开发的C/S结构,因为古老,当时也没有考虑到对产品的测试进行自动化,Client端并没有预留CLI(Command Line interface)形式的接口,真是雪上加霜啊。
那怎么自动化?采用AutoIT来对客户端界面进行自动化测试?可惜AutoIT对当初开发采用的控件识别不是很好,如果采用控件所在位置来进行控制的方式,又会导致自动化测试并不是很稳定。那么!!!只有自己开发接口了,目前在Client端开发出CLI形式的接口,将其封装为DLL,然后在Robot FrameWork框架中采用Python对DLL进行调用。任务艰巨哪!
Python调用DLL例子
示例一
首先,在创建一个DLL工程(本人是在VS 2005中创建),头文件:
[cpp] view plain 在CODE上查看代码片派生到我的代码片//hello.h
#ifdef EXPORT_HELLO_DLL
#define HELLO_API __declspec(dllexport)
#else
#define HELLO_API __declspec(dllimport)
#endif
extern "C"
{
HELLO_API int IntAdd(int , int);
}
CPP文件:
[cpp] view plain 在CODE上查看代码片派生到我的代码片//hello.cpp
#define EXPORT_HELLO_DLL
#include "hello.h"
HELLO_API int IntAdd(int a, int b)
{
return a + b;
}
这里有两个注意点:
(1)弄清楚编译的时候函数的调用约定采用的__cdecl还是__stdcall,因为根据DLL中函数调用约定方式,Python将使用相应的函数加载DLL。
(2)如果采用C++的工程,那么导出的接口需要extern "C",这样python中才能识别导出的函数。
我的工程中采用__cdecl函数调用约定方式进行编译链接产生hello.dll,然后Python中采用ctypes库对hello.dll进行加载和函数调用:
[python] view plain 在CODE上查看代码片派生到我的代码片from ctypes import *
dll = cdll.LoadLibrary('hello.dll');
ret = dll.IntAdd(2, 4);
print ret;
OK,一个小例子已经完成了,如果你感兴趣,但还没试过,那就尝试一下吧。
示例二
示例一只是一个"hello world"级别的程序,实际运用中更多的需要传递数据结构、字符串等,才能满足我们的需求。那么这个示例将展示,如何传递数据结构参数,以及如何通过数据结构获取返回值。
首先编写DLL工程中的头文件:
[cpp] view plain 在CODE上查看代码片派生到我的代码片//hello.h
#ifdef EXPORT_HELLO_DLL
#define HELLO_API __declspec(dllexport)
#else
#define HELLO_API __declspec(dllimport)
#endif
#define ARRAY_NUMBER 20
#define STR_LEN 20
struct StructTest
{
int number;
char* pChar;
char str[STR_LEN];
int iArray[ARRAY_NUMBER];
};
extern "C"
{
//HELLO_API int IntAdd(int , int);
HELLO_API char* GetStructInfo(struct StructTest* pStruct);}
CPP文件如下:
[cpp] view plain 在CODE上查看代码片派生到我的代码片//hello.cpp
#include <string.h>
#define EXPORT_HELLO_DLL
#include "hello.h"
HELLO_API char* GetStructInfo(struct StructTest* pStruct){
for (int i = 0; i < ARRAY_NUMBER; i++)
pStruct->iArray[i] = i;
pStruct->pChar = "hello python!";
strcpy (pStruct->str, "hello world!");
pStruct->number = 100;
return "just OK";
}
GetStructInfo这个函数通过传递一个StructTest类型的指针,然后对对象中的属性进行赋值,最后返回"just OK".
编写Python调用代码如下,首先在Python中继承Structure构造一个和C DLL中一致的数据结构StructTest,然后设置函数GetStructInfo的参数类型和返回值类型,最后创建一个StructTest对象,并将其转化为指针作为参数,调用函数GetStrcutInfo,最后通过输出数据结构的值来检查是否调用成功:
[python] view plain 在CODE上查看代码片派生到我的代码片from ctypes import *
ARRAY_NUMBER = 20;
STR_LEN = 20;
#define type
INTARRAY20 = c_int * ARRAY_NUMBER;
CHARARRAY20 = c_char * STR_LEN;
#define struct
class StructTest(Structure):
_fields_ = [
("number", c_int),
("pChar", c_char_p),
("str", CHARARRAY20),
("iArray", INTARRAY20)
]
#load dll and get the function object
dll = cdll.LoadLibrary('hello.dll');
GetStructInfo = dll.GetStructInfo;
#set the return type
GetStructInfo.restype = c_char_p;
#set the argtypes
GetStructInfo.argtypes = [POINTER(StructTest)];objectStruct = StructTest();
#invoke api GetStructInfo
retStr = GetStructInfo(byref(objectStruct));#check result
print "number: ", objectStruct.number;
print "pChar: ", objectStruct.pChar;
print "str: ", objectStruct.str;
for i,val in enumerate(objectStruct.iArray):
print 'Array[i]: ', val;
print retStr;
总结
1. 用64位的Python去加载32位的DLL会出错
2. 以上只是些测试程序,在编写Python过程中尽可能的使用"try Except"来处理异常3. 注意在Python与C DLL交互的时候字节对齐问题4. ctypes库的功能还有待继续探索
⑶ 我在网上找到的用python写的在windows下控制鼠标的操作,求高手讲解一下这个代码,本人新手,看不懂~~
这个就是直接用的winapi,你到msdn上搜相应的函数就知道了。
⑷ python byref是指针吗
handle = ctypes.c_int(0) ret = lib.XF_OpenDev(0, ctypes.byref(handle)) handle作为指针传进去后如果被改掉,返回的是一个c_int 或者c_long, 你可以通过handle.value来获得可以在python中灵活运用的真正的python整形
⑸ python3.2 下的抓包库。。无论是pypcap还是scapy。貌似都没有py3的版本。。跪求一个可以python3用
有一个py3kcap是pycap的封装版本,可以用于python3版本。
给你一个使用的示例代码:
#!/usr/bin/env python3.2
import ctypes,sys
from ctypes.util import find_library
#pcap = ctypes.cdll.LoadLibrary("libpcap.so")
pcap = None
if(find_library("libpcap") == None):
print("We are here!")
pcap = ctypes.cdll.LoadLibrary("libpcap.so")
else:
pcap = ctypes.cdll.LoadLibrary(find_library("libpcap"))
# required so we can access bpf_program->bf_insns
"""
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;}
"""
class bpf_program(ctypes.Structure):
_fields_ = [("bf_len", ctypes.c_int),("bf_insns", ctypes.c_void_p)]
class sockaddr(ctypes.Structure):
_fields_=[("sa_family",ctypes.c_uint16),("sa_data",ctypes.c_char*14)]
class pcap_pkthdr(ctypes.Structure):
_fields_ = [("tv_sec", ctypes.c_long), ("tv_usec", ctypes.c_long), ("caplen", ctypes.c_uint), ("len", ctypes.c_uint)]
pkthdr = pcap_pkthdr()
program = bpf_program()
# prepare args
snaplen = ctypes.c_int(1500)
#buf = ctypes.c_char_p(filter)
optimize = ctypes.c_int(1)
mask = ctypes.c_uint()
net = ctypes.c_uint()
to_ms = ctypes.c_int(100000)
promisc = ctypes.c_int(1)
filter = bytes(str("port 80"), 'ascii')
buf = ctypes.c_char_p(filter)
errbuf = ctypes.create_string_buffer(256)
pcap_close = pcap.pcap_close
pcap_lookupdev = pcap.pcap_lookupdev
pcap_lookupdev.restype = ctypes.c_char_p
#pcap_lookupnet(dev, &net, &mask, errbuf)
pcap_lookupnet = pcap.pcap_lookupnet
#pcap_t *pcap_open_live(const char *device, int snaplen,int promisc, int to_ms,
#char *errbuf
pcap_open_live = pcap.pcap_open_live
#int pcap_compile(pcap_t *p, struct bpf_program *fp,const char *str, int optimize,
#bpf_u_int32 netmask)
pcap_compile = pcap.pcap_compile
#int pcap_setfilter(pcap_t *p, struct bpf_program *fp);
pcap_setfilter = pcap.pcap_setfilter
#const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);
pcap_next = pcap.pcap_next
# int pcap_compile_nopcap(int snaplen, int linktype, struct bpf_program *program,
# const char *buf, int optimize, bpf_u_int32 mask);
pcap_geterr = pcap.pcap_geterr
pcap_geterr.restype = ctypes.c_char_p
#check for default lookup device
dev = pcap_lookupdev(errbuf)
#override it for now ..
dev = bytes(str("wlan0"), 'ascii')
if(dev):
print("{0} is the default interface".format(dev))
else:
print("Was not able to find default interface")
if(pcap_lookupnet(dev,ctypes.byref(net),ctypes.byref(mask),errbuf) == -1):
print("Error could not get netmask for device {0}".format(errbuf))
sys.exit(0)
else:
print("Got Required netmask")
handle = pcap_open_live(dev,snaplen,promisc,to_ms,errbuf)
if(handle is False):
print("Error unable to open session : {0}".format(errbuf.value))
sys.exit(0)
else:
print("Pcap open live worked!")
if(pcap_compile(handle,ctypes.byref(program),buf,optimize,mask) == -1):
# this requires we call pcap_geterr() to get the error
err = pcap_geterr(handle)
print("Error could not compile bpf filter because {0}".format(err))
else:
print("Filter Compiled!")
if(pcap_setfilter(handle,ctypes.byref(program)) == -1):
print("Error couldn't install filter {0}".format(errbuf.value))
sys.exit(0)
else:
print("Filter installed!")
if(pcap_next(handle,ctypes.byref(pkthdr)) == -1):
err = pcap_geterr(handle)
print("ERROR pcap_next: {0}".format(err))
print("Got {0} bytes of data".format(pkthdr.len))
pcap_close(handle)
⑹ python里面如何释放DLL文件
调用dll的代码采用如下顺序:
dll = CDLL(dllPath)
update_out = UpdateParamStruct()
dll.SeUpdaterGetParam(case.updateType, byref(update_out))
win32api.FreeLibrary(dll._handle)
这样就可以在执行完后,dll文件不会处于占用的状态了~
⑺ 如何用python解析获取C源文件的函数名
class stdata(Structure):
_fields_ = [('pBuf', c_char_p), ('buflen', c_int)]
N=100
buf = create_string_buffer(N)
d = stdata()
d.buflen = N
d.pBuf = cast(buf, c_char_p)
n = CallMyCFunc_GetData(byref(d))
关键在于create_string_buffer创建可写buffer;cast转换为char*类型。
⑻ 如何使用python 语言来实现测试开发
对于各种驱动接口,Python来编写测试用例的好处是:由于Python不需要编译,你所执行的也就是你所编写的,当发生异常的时候,你无须打开集成开发环境,加载测试工程、并调试,你能够很方便的看到python测试脚本的内容,什么地方出了异常可以立刻发现,例如:
from ctypes import *
rc =c_int(-12345);
dll = windll.LoadLibrary("dmodbc.dll");#加载被测试组件
#=================#
SQLHANDLE_env = pointer(c_long(0));
SQLHANDLE_cnn = pointer(c_long(0));
SQLHANDLE_stmt = pointer(c_long(0));
pdns = c_char_p("FASTDB");
puid = c_char_p("SYSDBA");
ppwd = c_char_p("SYSDBA");
#env handle
rc = dll.SQLAllocHandle(1,None,byref(SQLHANDLE_env));
print "result of henv handle alloc :%d" %rc;
#cnn handle
rc = dll.SQLAllocHandle(2,SQLHANDLE_env,byref(SQLHANDLE_cnn));
print "result of cnn handle alloc :%d" %rc;
#connect!
rc = dll.SQLConnect(SQLHANDLE_cnn,pdns,-3,puid,-3,ppwd,-3)
print "result of connect :%d" %rc;
#stmt handle
rc = dll.SQLAllocHandle(3,SQLHANDLE_cnn,byref(SQLHANDLE_stmt));
print "result of stmt handle alloc:%d" %rc;
#exec
rc = dll.SQLExecDirect(SQLHANDLE_stmt,"insert into t values(1)",-3);
print "result of exec:%d" %rc;
#free========================
rc = dll.SQLFreeHandle(3, SQLHANDLE_stmt);
print rc;
rc = dll.SQLDisconnect(SQLHANDLE_cnn);
print rc;
rc = dll.SQLFreeHandle(2, SQLHANDLE_cnn);
print rc;
rc = dll.SQLFreeHandle(1, SQLHANDLE_env);
print rc;
在上面我们可以看到,Python调用c/c++接口是十分容易的,只需要把动态库加载进来,然后把这个动态库当作一个对象实例来使用就可以了。下面将是一个使用ado.net接口的例子:
import System;
from Dm import *#Dm是DMDBMS提供的ado.Net的DataProvider
#print dir(Dm.DmCommand);
i =0;
cnn = Dm.DmConnection("server = 127.0.0.1; User ID = SYSDBA; PWD = SYSDBA; Database = SYSTEM; port = 12345");
cmd = Dm.DmCommand();
cmd.Connection = cnn;
cmd.CommandText = "insert into t values(1);";
cnn.Open();
i=cmd.ExecuteNonQuery();
print i;
cmd.Dispose();
cnn.Close();
可以看到,.net对象的使用与在VisualStdio上进行开发几乎没有任何区别。
通过使用Python进行测试用例的开发,最大的好处莫过于:学习成本非常低,测试工程师只需要学习Python,对于其他语言稍有了解就可以了。同时只需要少量的测试开发工程师对Python测试框架进行维护。
这样的好处就是便于测试人员将精力专精在一个方向,免于“什么都会一点,但什么都不精”的情况。当然测试人员具备广阔的知识面,会使用各种常见的开发工具与平台是好事情,并且也是必要的,不过在短时间内要求迅速能够胜任大多数任务也是企业在人才培养上的期望目标。