精华内容
下载资源
问答
  • 汇编代码注入器

    千次阅读 2014-08-22 17:28:55
    void CCodeInjectDlg::... // TODO: 在此添加控件通知处理程序代码 if (m_dwPid == 0) return; int nMaxCmdSize = (m_reAsmCode.GetLineCount() + 1) * MAXCMDSIZE; //最大申请的内存大小 HANDLE hProcess =

    这个是仿照以前的一个代码注入器写的,高手不要见笑了!其实上次已经写过一个,但是不小心系统重装给弄丢了,现在心血来潮又写了一个。

    小工具的功能只是注入汇编代码而已,无其他功能,现在我把它发到网上跟大家分享和交流,有什么问题欢迎指出!



    // CodeInjectDlg.h : 头文件
    //
    
    #pragma once
    #include "afxwin.h"
    #include "afxcmn.h"
    #include "disasm.h"
    
    
    // CCodeInjectDlg 对话框
    class CCodeInjectDlg : public CDialog
    {
    // 构造
    public:
    	CCodeInjectDlg(CWnd* pParent = NULL);	// 标准构造函数
    
    // 对话框数据
    	enum { IDD = IDD_CODEINJECT_DIALOG };
    
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
    
    
    // 实现
    protected:
    	HICON m_hIcon;
    
    	// 生成的消息映射函数
    	virtual BOOL OnInitDialog();
    	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    	afx_msg void OnPaint();
    	afx_msg HCURSOR OnQueryDragIcon();
    	afx_msg BOOL OnToolTip(UINT id,NMHDR *pNMHDR,LRESULT *pResult);
    	afx_msg void OnBnClickedButtonProcess();
    	DECLARE_MESSAGE_MAP()
    public:
    	DWORD m_dwPid;
    	CString m_strPid;
    	CString m_strProcessName;
    	afx_msg void OnBnClickedButtonInject();
    	CRichEditCtrl m_reAsmCode;
    	bool Asm2Machinecode(char* pAsmcode, DWORD dwAddrress, __out t_asmmodel* pMachinecode);
    	bool Asm2Machinecode(TCHAR* pSrcAsmcode, DWORD dwAddrress, __out t_asmmodel* pMachinecode);
    };
    

    // CodeInjectDlg.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "CodeInject.h"
    #include "CodeInjectDlg.h"
    #include "ProcessDlg.h"
    
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    
    // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
    
    class CAboutDlg : public CDialog
    {
    public:
    	CAboutDlg();
    
    // 对话框数据
    	enum { IDD = IDD_ABOUTBOX };
    
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
    // 实现
    protected:
    	DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    END_MESSAGE_MAP()
    
    
    // CCodeInjectDlg 对话框
    
    
    
    
    CCodeInjectDlg::CCodeInjectDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CCodeInjectDlg::IDD, pParent)
    	, m_strPid(_T(""))
    	, m_strProcessName(_T(""))
    {
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    	m_dwPid = 0;
    }
    
    void CCodeInjectDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	DDX_Text(pDX, IDC_EDIT_PID, m_strPid);
    	DDX_Text(pDX, IDC_EDIT_PROCESSNAME, m_strProcessName);
    	DDX_Control(pDX, IDC_RICHEDIT21, m_reAsmCode);
    }
    
    BEGIN_MESSAGE_MAP(CCodeInjectDlg, CDialog)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTip)
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(IDC_BUTTON_PROCESS, &CCodeInjectDlg::OnBnClickedButtonProcess)
    	ON_BN_CLICKED(IDC_BUTTON_INJECT, &CCodeInjectDlg::OnBnClickedButtonInject)
    END_MESSAGE_MAP()
    
    
    // CCodeInjectDlg 消息处理程序
    
    BOOL CCodeInjectDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// 将“关于...”菜单项添加到系统菜单中。
    
    	// IDM_ABOUTBOX 必须在系统命令范围内。
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		CString strAboutMenu;
    		strAboutMenu.LoadString(IDS_ABOUTBOX);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    	//  执行此操作
    	SetIcon(m_hIcon, TRUE);			// 设置大图标
    	SetIcon(m_hIcon, FALSE);		// 设置小图标
    
    
    	// TODO: 在此添加额外的初始化代码
    	EnableToolTips(TRUE);
    
    	// 设置按钮图片
    	HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),
    		MAKEINTRESOURCE(IDI_ICON_PROCESS),
    		IMAGE_ICON,
    		16,
    		16,
    		LR_DEFAULTCOLOR);
    
    	((CButton*)GetDlgItem(IDC_BUTTON_PROCESS))->SetIcon(hIcon);
    
    	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    
    void CCodeInjectDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    	{
    		CAboutDlg dlgAbout;
    		dlgAbout.DoModal();
    	}
    	else
    	{
    		CDialog::OnSysCommand(nID, lParam);
    	}
    }
    
    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。
    
    void CCodeInjectDlg::OnPaint()
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // 用于绘制的设备上下文
    
    		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
    		// 使图标在工作矩形中居中
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// 绘制图标
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		CDialog::OnPaint();
    	}
    }
    
    //当用户拖动最小化窗口时系统调用此函数取得光标显示。
    //
    HCURSOR CCodeInjectDlg::OnQueryDragIcon()
    {
    	return static_cast<HCURSOR>(m_hIcon);
    }
    
    BOOL CCodeInjectDlg::OnToolTip( UINT id,NMHDR *pNMHDR,LRESULT *pResult )
    {
    	TOOLTIPTEXT *pTTT = (TOOLTIPTEXT*)pNMHDR;
    	HWND hWnd = (HWND)pNMHDR->idFrom;
    	int nID = 0;
    	if (pTTT->uFlags & TTF_IDISHWND)
    		nID = ::GetDlgCtrlID(hWnd);
    
    	if (nID == 0)
    		return FALSE;
    
    	switch (nID)
    	{
    	case IDC_BUTTON_PROCESS:
    		pTTT->lpszText = _T("选择目标进程");
    		break;
    	}
    
    	return TRUE;
    }
    
    void CCodeInjectDlg::OnBnClickedButtonProcess()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	CProcessDlg dlg;
    	if (dlg.DoModal() == IDOK)
    	{
    		m_strProcessName = dlg.m_strProcessName;
    		m_strPid = dlg.m_strPid;
    		int nFind1 = m_strPid.Find('[');
    		int nFind2 = m_strPid.Find(']');
    		if (nFind2 > 0)
    		{
    			CString str = m_strPid.Mid(nFind1 + 1, nFind2 - nFind1 - 1);
    			m_dwPid = _ttoi(str);
    		}
    		UpdateData(FALSE);
    	}
    }
    
    void CCodeInjectDlg::OnBnClickedButtonInject()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	if (m_dwPid == 0)
    		return;
    
    	int nMaxCmdSize = (m_reAsmCode.GetLineCount() + 1) * MAXCMDSIZE; //最大申请的内存大小
    	HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwPid);
    	PVOID pLibRemote = ::VirtualAllocEx(hProcess, NULL, nMaxCmdSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    	DWORD dwStartAddr = (DWORD)(PDWORD)pLibRemote;
    
    	t_asmmodel am;
    	memset(&am, 0, sizeof(am));
    	TCHAR *pBuf;
    	int nLineLength;
    	bool bOK = true;
    	for (int i = 0; i < m_reAsmCode.GetLineCount(); i++)
    	{
    		nLineLength = m_reAsmCode.LineLength(i);
    		if (nLineLength == 0)
    			continue;
    
    		pBuf = new TCHAR[nLineLength + 4];
    		m_reAsmCode.GetLine(i, pBuf, nLineLength + 4);
    
    		if (Asm2Machinecode(pBuf, dwStartAddr, &am)) //汇编转机器码
    		{
    			::WriteProcessMemory(hProcess, (void*)dwStartAddr, (void*)am.code, am.length, NULL);
    			dwStartAddr += am.length;
    		}
    		else
    			bOK = false;
    
    		delete []pBuf;
    	}
    	
    	Asm2Machinecode(_T("xor eax,eax"), dwStartAddr, &am);
    	::WriteProcessMemory(hProcess, (void*)dwStartAddr, (void*)am.code, am.length, NULL);
    	dwStartAddr += am.length;
    	Asm2Machinecode(_T("retn 0"), dwStartAddr, &am);
    	::WriteProcessMemory(hProcess, (void*)dwStartAddr, (void*)am.code, am.length, NULL);
    
    	if (bOK)
    	{
    		HANDLE hThread;
    		CString strThreadAddr;
    		hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLibRemote, NULL, 0, 0);
    		strThreadAddr.Format(_T("%08X"), pLibRemote);
    		SetDlgItemText(IDC_EDIT_THREADADDR, strThreadAddr);
    		CloseHandle(hThread);
    	}
    	else
    	{
    		AfxMessageBox(_T("代码有误!"));
    	}
    	::VirtualFreeEx(hProcess, pLibRemote, nMaxCmdSize, MEM_RELEASE);
    	CloseHandle(hProcess);
    }
    
    bool CCodeInjectDlg::Asm2Machinecode(char* pAsmcode, DWORD dwAddrress, __out t_asmmodel* pMachinecode)
    {
    	bool bResult;
    	char errtext[TEXTLEN];
    	Assemble(pAsmcode,dwAddrress,pMachinecode,0,0,errtext);
    	bResult = pMachinecode->length > 0;
    
    	return bResult;
    }
    
    bool CCodeInjectDlg::Asm2Machinecode(TCHAR* pSrcAsmcode, DWORD dwAddrress, __out t_asmmodel* pMachinecode)
    {
    	bool bResult;
    	char errtext[TEXTLEN];
    
    	//Unicode转Ansi
    	int nLen = WideCharToMultiByte(CP_OEMCP, 0, pSrcAsmcode, -1, NULL, 0, NULL, FALSE);
    	char* pAsmcode = new char[nLen];
    	WideCharToMultiByte(CP_OEMCP, 0, pSrcAsmcode, -1, pAsmcode, nLen, NULL, FALSE);
    	//=====================================================================================
    	for (size_t i = 0; i < strlen(pAsmcode); i++)
    	{
    		if (pAsmcode[i] == '\r' || pAsmcode[i] == '\n')
    			pAsmcode[i] = 0;
    	}
    	Assemble(pAsmcode,dwAddrress,pMachinecode,0,0,errtext);
    	//TRACE(pAsmcode);
    	delete []pAsmcode;
    	bResult = pMachinecode->length > 0;
    
    	return bResult;
    }
    

    展开全文
  • 使用Smali代码注入

    千次阅读 2014-11-15 17:05:36
    阅读该教程中需要读者具有Android虚拟机语言smali的语法基础和openGL的基础...1.首先下载到手最新的魅拍apk包,魅拍是腾讯旗下子公司做的一款图片滤镜软件,使用apktool.jar反编译该apk包: 获得的文件夹中有一个s

    http://androiddeveloper.diandian.com/post/2013-04-12/40048563235

    阅读该教程中需要读者具有Android虚拟机语言smali的语法基础和openGL的基础,读者可以在

    http://bbs.pediy.com/showthread.php?t=151769

    获得基本的smali语法知识。下面进入正题:

    1.首先下载到手最新的魅拍apk包,魅拍是腾讯旗下子公司做的一款图片滤镜软件,使用apktool.jar反编译该apk包:


    获得的文件夹中有一个smali文件夹,它是整个项目的smali源码。

    2.每个openGL滤镜在着色的时候都会使用glShaderSource函数来Shader着色器的代码,所以在smali目录下搜索该字符串:

    3.找到关键代码后,打开该文件,找到调用的函数:


    寄存器p1中的内容就是我们想要的shader脚本,在该函数之后使用代码注入输出着色器的shader脚本:


    这里使用v1寄存器来存储PrintStream,因为观察后面的代码中v1寄存器直接被赋值了,赋值之前并没被读取过,所以这里借用v1寄存器。

    4.重新使用apktool.jar打包代码注入过的魅拍文件夹


    5.将打包后的meipai.apk使用自己的签名秘钥签名(利用signapk.jar包),最后安装代码注入后的apk包,安装后打开魅拍进入移轴滤镜页,点击移轴效果,将看到shader脚本被打印出来:


    6.最后发现,该openGL脚本中存在外部变量,寻找到特殊变量如outerRadius,在smali文件目录下寻找就能找到它在文件中赋值的位置,最后继续代码注入打印出所有参数的值:


    768.0是width,1024.0是height等等。。。。魅拍移轴滤镜的算法就破解了

    展开全文
  • 本文就来解答上一篇文章留下的疑问,为什么在注入器也分成了instance注入器和provider注入器。这两种注入器的工作原理是怎么样的。 总体结构 为此我特别准备了一张图来描述一下angular注入器的工作流程和原理,...

    本文就来解答上一篇文章留下的疑问,为什么在注入器也分成了instance注入器和provider注入器。这两种注入器的工作原理是怎么样的。

    总体结构

    为此我特别准备了一张图来描述一下angular注入器的工作流程和原理,如下所示。

    angular注入器工作流程和原理

    这张图的顶部是外部调用的入口,即通过angular暴露给外部的$injector服务。关于$injector服务中含有的五个方法,在$injector服务中已经介绍过了,在本文中就不再赘述了。还不清楚$injector服务是个啥的同学可以先去看看那篇文章。

    那么暴露给外部使用的$injector是哪种注入器呢?从图中可以很清晰的看出,暴露的是实例注入器(Instance Injector)。所谓的实例注入器,就是用来保存各种被实例化了的托管对象。这些实例在实例化之后会被保存在它对应的一个叫做实例注入器缓存的地方,也就是图中的cache(instanceCache)所指向的区域。下面我们就来看看实例注入器的相关代码。

    instance注入器

    instanceCache = {},
    protoInstanceInjector =
        createInternalInjector(instanceCache, function(serviceName, caller) {
          var provider = providerInjector.get(serviceName + providerSuffix, caller);
          return instanceInjector.invoke(
              provider.$get, provider, undefined, serviceName);
        }),
    instanceInjector = protoInstanceInjector;
    
    // createInternalInjector的函数签名
    function createInternalInjector(cache, factory) { 
      // ......
    }
    
    // factory在getService函数中被用到
    function getService(serviceName, caller) {
      if (cache.hasOwnProperty(serviceName)) {
        if (cache[serviceName] === INSTANTIATING) {
          throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
                    serviceName + ' <- ' + path.join(' <- '));
        }
        return cache[serviceName];
      } else {
        try {
          path.unshift(serviceName);
          cache[serviceName] = INSTANTIATING;
          // 注意下面这一行代码的行为,调用factory得到实例然后保存并返回
          return cache[serviceName] = factory(serviceName, caller);
        } catch (err) {
          if (cache[serviceName] === INSTANTIATING) {
            delete cache[serviceName];
          }
          throw err;
        } finally {
          path.shift();
        }
      }
    }

    注入器本身的实例是通过调用createInternalInjector函数得到。该函数需要接受两个参数,第一个参数cache表示注入器使用的缓存是哪一个。第二个参数factory是一个函数,当需要的实例不存在时就会调用这个函数来进行实例化,得到的对象会被放入到第一个参数所指定的缓存中。

    那让我们来看看实例注入器是如何声明这个factory函数的:

    // providerSuffix实际上就是一个字符串:Provider
    var providerSuffix = 'Provider';
    
    createInternalInjector(instanceCache, function(serviceName, caller) {
      var provider = providerInjector.get(serviceName + providerSuffix, caller);
      return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);
    }),

    很明显的是,在实例注入器的factory函数中发生了和provider注入器的互动。它会去provider注入器中寻找一个provider对象,然后通过实例注入器来调用provider对象上的$get方法,来最终得到需要的对象实例。这个过程在前文的总体结构图中也反映出来了,实例注入器指向provider注入器的箭头表达的就是这个意思,即它会将托管对象实例化的工作委托给保存在provider注入器中的某个provider。具体而言,是委托给了provider对象上的$get方法。该方法最终会被实例注入器通过invoke方法进行调用。既然$get方法是通过注入器的invoke方法而调用,因此在$get方法中开发人员也可以声明它所需要的各种依赖。

    provider注入器

    简要分析了实例注入器之后,下面来看看另一个主角 - provider注入器。
    它的创建过程是这样的:

    providerCache = {
      $provide: {
          provider: supportObject(provider),
          factory: supportObject(factory),
          service: supportObject(service),
          value: supportObject(value),
          constant: supportObject(constant),
          decorator: decorator
        }
    },
    providerInjector = (providerCache.$injector =
      createInternalInjector(providerCache, function(serviceName, caller) {
        if (angular.isString(caller)) {
          path.push(caller);
        }
        throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
      }));

    首先,providerCache在初始化的时候就已经有一个$provide对象了。这个对象中定义了我们很熟悉的providerfactoryservice等一系列我们能够在module上定义的服务类型。至于这些方法的是做什么用的,如何使用的,我们后面会专门进行分析。本文暂且先专注于注入器实现的总体结构和执行流程。

    然后还是通过createInternalInjector函数来完成provider注入器的创建工作。创建得到的注入器也会被保存到providerCache中。而该注入器提供的factory函数的定义也特别简单。就是记录一下调用的顺序,然后抛出异常。为什么直接抛出找不到provider的异常?因为如果在providerCache中都找不到我们需要的provider对象,就没有必要继续寻找下去了,毕竟只有两个注入器不是嘛。实例注入器可以委托provider注入器,但是provider注入器可没别的注入器依赖。这也是为什么providerCache在初始化的时候就已经有一个$provide对象的原因。因为这个$provide对象上定义的方法可不简单,它们的职责就是创建我们开发人员在module上定义的各种服务。如果没有它们的存在,那每次定义服务都会抛出Unknown Provider异常了不是吗。

    另外值得一提的是,在创建了实例注入器和provider注入器之后,还有这么一行代码:

    providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
    
    // valueFn的定义
    function valueFn(value) {return function valueRef() {return value;};}

    它将实例注入器的通过$injectorProvider这个键值给注册到了providerCache中去。
    所以,当我们在自定义的servicefactorycontroller中指定需要$injector时,得到的都会是实例注入器,而非provider注入器。这个过程也很清晰,当你需要$injector时,实例注入器会委托给provider注入器,provider注入器去寻找一个名为$injectorProviderprovider对象,并调用其$get方法返回真正的实例。

    为什么要这样实现

    看清楚了angular注入器的实现原理和流程,我们来思考一下为什么它会这么设计。这个问题也许只有开发这个功能的人才能最终解释清楚。但是这一点是很明显的:

    隐藏不必要的信息,将功能的入口单一化。也就是所谓的门面模式(Facade Pattern)。这个门面就是angular中的module。我们注册各种服务都是使用的module上的对应方法,作为开发人员只需要了解清除module上的各种方法的使用规则就可以了,没有知道底层还有个$injector服务的必要。就算开发的功能比较复杂,需要使用到$injector服务了,也确实没有必要需要知道这个$injector服务实际上是由两个injector联合提供的。这也是软件开发的基本规则之一,即使软件提供的功能很复杂,对外暴露的也要尽可能地简单易懂。否则你这个软件还怎么用,难道要用之前得看一遍源代码理解其内部实现才行吗。


    但是学习angular中注入器的设计和实现也是一件非常有意思的事情,真的是开拓了眼界。一个框架的重要功能原来是这么实现的,一点一点地去分析去思考也是能够看懂背后的逻辑的,毕竟再复杂的程序也是一行一行代码垒起来的。

    展开全文
  • HttpCanary使用指南——静态注入器

    万次阅读 2019-03-01 17:03:18
    !! 静态注入器是HttpCanary最强大的功能之一,可以实现对Http请求数据和响应数据的拦截...比如App发往服务器的请求为:https://test.com?city=beijing ,我们可以使用HttpCanary的静态注入器将参数值beijing修改为...

    HttpCanary更多资料,点我!!!

    静态注入器是HttpCanary最强大的功能之一,可以实现对Http请求数据和响应数据的拦截修改。静态注入器需要先选定一个请求,然后对其进行预编辑,编辑完成后便可对后续的相同请求进行自动修改。

    比如App发往服务器的请求为:https://test.com?city=beijing ,我们可以使用HttpCanary的静态注入器将参数值beijing修改为nanjing 。对App的开发和测试而言,可以模拟很多不同场景的请求,来提高测试效率。

    本篇文章将详细讲解如何使用静态注入器。

    测试请求范例

    https://www.apiopen.top/weatherApi?city=北京
    复制代码

    创建静态注入器

    首先,长按抓包记录,在弹框中选择“静态注入“,然后给注入器命名(方便后面对注入器进行管理)。

    命名完成后,进入注入器编辑界面。编辑页面会展示出此请求的所有Http协议数据,包括请求行(Start Line)、请求头(Headers)、请求体(Body)、状态行(StatusLine)、响应头(Headers)、响应体(Body)。

    左边Tab是请求数据,右边是响应数据。

    关于Http协议的报文结构,下面这张图做了详细描述(图中非范例请求数据),更多内容请见:https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages

    在了解Http协议报文之后,我们下面开始讲解如何使用注入器修改数据。

    1. URL参数修改

    我们希望将请求参数city的值由北京修改为南京

    https://www.apiopen.top/weatherApi?city=南京
    复制代码

    只需要点击”city=北京“这个参数区域。

    打开URL参数编辑页后,将参数值由北京改为南京,并保存。

    修改完成后,返回注入器页面。city前面的点颜色由灰色变为绿色,表示参数是修改状态。即如果后续相同请求参数中包含city参数,其值会被强制替换成南京

    点击右上角完成注入器的创建。

    下面我们重新用AppTest应用发送一条相同的请求,来测试修改是否能生效。抓到包后,打开抓包内容详情:

    由于南京是中文,作为URL一部分会被Encode,不怕,我们点击这个URL打开URL预览页:

    我们最后再来看看响应数据,确认下是否是真的生效了。

    完美!

    2. URL参数添加和删除

    如果我们希望将请求修改为这种:

    https://www.apiopen.top/weatherApi?province=江苏&days=7
    复制代码

    删除city参数,新增province和days参数。

    同样先按照上一步的步骤打开静态注入器编辑页面。点击city参数右侧的三个点按钮,打开功能选择弹框,一共有三个选项:跟随,自定义,禁用。

    这里解释下三个选项的含义。

    • 跟随,表示使用原始数据,不做任何修改(默认选项),颜色为灰色。
    • 自定义,表示强行覆盖或添加设定的参数值,颜色为绿色。
    • 禁用,表示强行删除此参数和值,颜色为红色。

    所以,删除city参数,我们选择禁用选项,注意参数前面的点变成了红色。

    下一步,点击新增按钮添加两个参数,province=江苏和days=7。

    点击右上角保存,完成注入器创建后,我们重新再发一条请求,看看效果。

    很明显,city参数没有了,多了province和days两个参数。

    完美!

    3. Headers修改、添加和删除

    同上面URL操作相同,参考1和2,不再赘述。

    4. 响应行(Status Line)修改

    Http协议中响应行用来表示请求服务的结果状态,比如常用的200表示成功,404表示资源未找到,500表示服务器异常等等。

    有的时候为了测试一些极端情况,比如服务器不返回200而是404,App状态是否会出现bug等。我们可以使用HttpCanary来强行修改响应行中的状态码来实现这种效果。

    点击编辑按钮,打开列表,其中列出来几乎所有常用的响应行(都是标准响应行),我们从列表中选择404 Not Found。

    选择后自动返回,如果想撤销操作,点击右边复位按钮。

    我们点击右上角保存按钮完成注入器的创建,重新用AppTest应用发送一条相同请求。从下图中能看出,后面接收到的请求已经是404 Not Found了。

    完美!

    5. 请求/响应体(Body)修改

    在App实际开发和测试中,修改请求数据和返回数据是最经常用到的。比如,测试地理位置相关接口时,需要修改经纬度;再比如,服务器返回了某些时间戳,我们希望将其延长或者缩短。

    同样以此天气接口为例,希望将响应体中的yesterday的high改为100℃,low改为-100℃,type改为冰雹

    打开创建静态注入器的页面后,拉到最下面。点击右侧向上的箭头,选择编辑方式。

    静态注入器提供了两种方式用来编辑Body:上传文件和直接编辑。如果Body是二进制格式数据(比如音频、视频、ProtoBuffer等),HttpCanary内置的文本编辑器是无法处理的,只能使用上传文件的方式。如果Body是json、xml、fromdata等文本格式,可以使用直接编辑。

    由于接口返回的天气数据是JSON格式,我们可以使用直接编辑选项,打开后直接进行数据修改。

    保存后完成静态注入器的创建,用AppTest应用再发送一条相同请求,来看看结果。

    修改成功!完美!

    5. 静态注入器管理

    静态注入器和我们常用的断点(BreakPoint)方式修改数据不同,它是通过预设的方式来拦截和修改数据,可以极大地提高数据修改的效率。

    HttpCanary可以对一个请求配置多个静态注入器,按照先配置先生效的原则进行拦截处理。静态注入器一旦创建了,将会以Mod的形式作为插件功能存在于HttpCanary中,即使是杀掉HttpCanar APP后再重启也能生效。

    那我们如何对注入器进行管理呢?打开设置->模组管理页面,能看到所有创建的静态注入器。

    点击进入详情后,能看到注入器是属于哪个请求的。

    如果需要删除或者禁用已经创建的静态注入器,只需要在列表页长按打开功能选项即可!

    结语

    如果您对HttpCanary有任何疑问或者建议,可以访问HttpCanary Github并创建issue!

    静态注入器的使用指南到此结束,感谢您的阅读!

    展开全文
  • Android安全:代码注入

    千次阅读 2016-11-25 05:18:30
    一、常用的Smail注入代码 在逆向分析APK文件的时候,我们往往需要注入一些自己的代码方便调试,如增加调试Log信息等。常用的Smail注入代码如下: 1.增加调试Log信息: Log.i("test","Log Test"); 2.增加堆栈跟踪...
  • Jar代码注入

    千次阅读 2016-03-04 11:34:13
    通过使用Javassist这个类库,可以很方便的进行字节码的操作。 从这个角度讲,有很多我们之前没有想到的方面也可以进行实施。比如说有这么一个jar包,需要进行引用开发,于是乎,我们可以进行一些简单的恶作剧
  • 注入器/injector

    千次阅读 2017-07-25 23:00:44
    注入器/injector 注入器是AngularJS框架实现和应用开发的关键,这是一个DI/IoC容器的实现。 AngularJS将功能分成了不同类型的组件分别实现,这些组件有一个统称 - 供给者/provider, 下图中列出了AngularJS几个...
  • 动软代码生成注意事项-Sql注入

    千次阅读 多人点赞 2013-12-27 10:59:22
    动软可以说是一款很好的代码生成软件,只要有数据库,那么除了U层以外的代码都可以生成了,自动生成三层架构的完整项目和代码。   1、动软介绍   动软可以生成基于面向对象的思想和三层架构设计的代码,结合了...
  • Windows下的代码注入

    千次阅读 2018-09-09 18:55:39
    木马和病毒的好坏很大程度上取决于它的隐蔽性,木马和病毒本质上也是在执行程序代码,如果采用独立进程的方式需要考虑隐藏进程否则很容易被发现,在编写这类程序的时候可以考虑将代码注入到其他进程中,借用其他进程...
  • 使用汇编语言编写注入代码

    千次阅读 2018-10-06 23:22:49
    这里主要借助OllyDbg的汇编功能,使用汇编语言编写注入代码即ThreadProc()函数。与上一篇文章的CodeInject.cpp代码类似,但区别在于THREAD_PARAM结构体不包含字符串成员,且使用指令字节数组替代了ThreadProc()函数...
  • 代码注入漏洞介绍和修复参考

    千次阅读 2016-06-16 19:15:11
    代码注入 Shell注入 我们先来看一段perl的代码: use CGI qw(:standard); $name = param('name'); $nslookup = "/path/to/nslookup"; print header; if (open($fh, "$nslookup $name|")) { while ()
  • 第五课 代码注入(C语言)

    千次阅读 2018-09-04 21:18:42
    下面用一个代码注入示例向notepad.exe进程注入简单的代码,注入后会弹出消息框,显示消息 首先,运行notepad.exe 查看notepad.exe的PID,我这里显示的是2608 · 在cmd窗口中运行CodeInjection.exe 并输入命令与...
  • 3、SQL 注入器

    千次阅读 2021-07-07 22:51:40
    该栏目会系统的介绍 MyBatis Plus 的知识体系,共分为简介、常用API、SQL注入器代码生成器等模块 文章目录SQL 注入原理自定义 SQL 注入 SQL 注入原理 AbstractSqlInjector 中,主要由 inspectInject()方法 进行...
  • Java 防SQL注入过滤器代码

    万次阅读 2018-01-14 18:55:22
    所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,达到一定的非法用途。 解决办法 1、配置WEB-INF/web.xml web-app&...
  • 代码注入的三种方式

    万次阅读 2018-02-28 16:40:52
    WriteProcessMemory 技术――如何用该技术子类化远程控件――何时使用 CreateRemoteThread 和 WriteProcessMemory 技术结束语附录A附录B附录C附录D附录E附录F参考资料简介本文将讨论如何把代码注入不...
  • 一般我们习惯通过setter进行注入,例如Spring代码实例系列-02:松耦合loose coupling等都是setter注入,本章给与一个简单的构造器注入实例。主要应用到的技术有: 1. 注入bean 2. setter注入 3. constructor注入 ...
  • 在VC中,读取远程基址比较常用的方法有几种:可以采用hook钩子函数,也可采用windows API 远程进程函数对内存进行读取,然后获得远程进程在本机中的数据,并进行相关代码注入,获取更高的执行效率。比较常见的API...
  • iOS开发使用WKWebView与js交互使用WKUserScript注入js代码 新的改变 我们对Markdown编辑进行了一些功能拓展与语法支持,除了标准的Markdown编辑功能,我们增加了如下几点新功能,帮助你用它写博客: 全新的...
  • XSS攻击之HTTP代码注入

    千次阅读 2016-03-30 21:25:47
    我们进行代码注入攻击,就是在这几个地方进行。 一、标签绕过 1、对标签名进行大小写混合,并不影响代码执行,有时却可以绕过过滤。如: 2、利用现代浏览器对XHTML的支持,可以在某些浏览器的某些版本插入...
  • 本篇文章继续介绍angular中实现依赖注入的”幕后英雄” — 注入器(Injector)。说它是”幕后英雄”,是因为它才是依赖注入得以实现的主力军。而上篇文章介绍的模块只不过是活跃在前台跟各位开发人员直接打交道的”...
  • C++ DLL注入和代码注入

    千次阅读 2013-10-04 09:42:10
    另一种是直接注入代码代码如下: //函数名:InjectCode //功能:封装远程注入的函数 //参数:进程ID //参数:被注入函数指针<函数名> //参数:参数 //参数:参数长度   ...
  • 我们进行系统级别的安全监控的时候,防范木马的时候,经常需要进行远程代码注入执行。执行步骤如下1. 提升进程权限,如果权限不够的话,很容易造成 OpenProcess 失败;2. 确定你的宿主进程,即你所要注入代码的进程,...
  • 上一篇文章初次介绍了注入器(Injector),分析了它加载模块的过程以及它是如何执行任务队列的。这里需要重申一下的是,所谓任务队列实际上就是我们在开发一个基于angular的应用时定义的那些`constant`,`service`,`...
  • DLL注入器编写

    千次阅读 2018-09-29 09:38:38
    花了些时间写了个DLL注入器。  基本原理  进程对象在windows中,地址空间基本都是相对独立的,一 个进程无法操作其他进程的空间,但是通过创建远程进程的线程,在原 来进程的主线程之上添加一个线程,该线程属...
  • 转载自我的小站:原文地址通过Mono.Cecil我们可以通过Emit的方式将代码注入到已有的dll中,以实现AOP等高级功能。 Unity的代码在修改之后会自动编译到Library\ScriptAssemblies下的两个Assembly中,所以我会尝试着...
  • Xcode插件Injection实现代码注入

    千次阅读 2017-01-14 20:08:40
    Injection是johnno开发的一个Xcode插件,允许我们将代码实现更快注入到模拟器运行的程序或macOS程序。原先可以通过Alcatraz安装到Xcode中,不过现在是独立的App了。可以在 ...
  • Gradle-初探代码注入Transform

    千次阅读 2019-05-29 09:33:50
    APK打包器使用调试或者发布密钥库签署你的APK: 如果你构建的是debug版本应用,打包器会使用debug密钥库签署你的应用,Android Studio自动使用debug密钥库配置新项目 如果你构建的是release版本,打包器会使用...
  • HTML5 App的代码注入攻击

    千次阅读 2015-09-22 17:26:00
    摘要 ...它开发起来很方便,可以使用标准的web技术,包括HTML5、JavaScript 和 CSS,也可以借助一些现有的开发框架(比如PhoneGap)和手机操作系统...众所周知,JavaScript是非常容易遭受代码注入攻击的,因此我们计划

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 249,808
精华内容 99,923
关键字:

代码注入器使用