• AspectJ截获操作


    package com.example.aspectjandroidtest;
    
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    
    import org.apache.http.util.EncodingUtils;
    
    import com.facebook.crypto.Crypto;
    import com.facebook.crypto.Entity;
    import com.facebook.crypto.keychain.SharedPrefsBackedKeyChain;
    import com.facebook.crypto.util.SystemNativeCryptoLibrary;
    
    public aspect FileAspectJ {
    
    	private boolean isEncryption = true;
    	//使用秘钥链和原生库的默认实现,来创建一个新的加密对象
    	Crypto crypto = new Crypto(
    			new SharedPrefsBackedKeyChain(MainActivity.context), 
    			new SystemNativeCryptoLibrary());
    	
    	//创建应用文件的切点集合
    	pointcut openFileOutput(String filename,int mode) : !within(FileAspectJ) && args(filename,mode) && call(* openFileOutput(..));
    	after (String filename,int mode) returning : openFileOutput(filename, mode){
    		//System.out.println("fx Aspectj openFile is start");
    		byte[] buffer;
    		try {
    			System.out.println("fx Aspectj openFileName"+filename);
    			buffer = filename.getBytes("UTF8");
    			FileOutputStream fileOutputStream = null;
    			try {
    				//记录本应用加密过的文件
    				fileOutputStream = MainActivity.context.openFileOutput("fileList",
    						MainActivity.context.MODE_APPEND);
    			} catch (FileNotFoundException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			try {
    				fileOutputStream.write(buffer);
    				fileOutputStream.close();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		} catch (UnsupportedEncodingException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	
    	//读取应用文件的切点集合
    		pointcut openFileInput(String filename) : !within(FileAspectJ) && args(filename) && call(* openFileInput(..));
    		before(String filename) : openFileInput(filename){
    			
    			String result = "";
    			try {
    				FileInputStream fileInputStream = MainActivity.context.openFileInput("fileList");
    				int bufferSize = 0;
    				try {
    					bufferSize = fileInputStream.available();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} // 取得输入流的字节长度
    				byte buffer[] = new byte[bufferSize];
    				try {
    					fileInputStream.read(buffer);
    					fileInputStream.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				result = EncodingUtils.getString(buffer, "UTF-8");
    			} catch (FileNotFoundException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			//判断文件是否加密过
    			if(result.indexOf(filename) == -1){
    				isEncryption = false;//未加密
    				System.out.println("fx 文件未加密");
    			}else{ 
    				isEncryption = true;//已加密
    				System.out.println("fx 文件已加密");
    			}
    		}
    	
    		//截获到File的new操作
    		pointcut filePointcut(String pathname ) :  !within(FileAspectJ) && args(pathname) && call(java.io.File.new(..));
    		before(String pathname ) : filePointcut(pathname) {
    			System.out.println("fx pathname is " + pathname);
    		}
    		
    	//写文件切点的集合
    	pointcut writePointcut(FileOutputStream fileStream, byte[] buffer) : !within(FileAspectJ) && target(fileStream)&& args(buffer) && call(* write(..));
    	void around(FileOutputStream fileStream, byte[] buffer) : writePointcut(fileStream, buffer) {
    		System.out.println("fx Aspectj write is start");
    		//检查加密功能是否可用
    		//如果Android没有正确载入库,则此步骤可能失败
    		if (!crypto.isAvailable()) {
    			System.out.println("return error");
    			return;
    		}
    		OutputStream fbFileStream = new BufferedOutputStream(fileStream);
    		try {
    			//创建输出流,当数据写入流的时候进行加密,并将加密后的数据输出到文件
    			OutputStream outputStream = crypto.getCipherOutputStream(
    					fbFileStream, new Entity("test"));
    			outputStream.write(buffer);
    			outputStream.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	//读文件切点集合
    	pointcut readPointcut(FileInputStream fileStream, byte[] buffer) : !within(FileAspectJ) && target(fileStream)&& args(buffer) && call(* read(..));
    	int around(FileInputStream fileStream, byte[] buffer) : readPointcut(fileStream, buffer) {
    		System.out.println("fx Aspectj read is start");
    		int bufferSize = 0;
    		if(isEncryption==false){
    			return 0;
    		}
    		try {
    			//文件流解密操作
    			InputStream inputStream = crypto.getCipherInputStream(fileStream,	new Entity("test"));
    			bufferSize = inputStream.available(); // 取得输入流的字节长度
    			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    	        byte[] data = new byte[1024];
    			int len;
    			 if (inputStream != null) {
    		            try {
    		                while ((len = inputStream.read(data)) != -1) {
    		                    outputStream.write(data, 0, len);
    		                }
    		                data = outputStream.toByteArray();
    		            } catch (IOException e) {
    		            }
    		        }
    			 for(int i = 0;i<data.length;i++) {
    				 buffer[i] = data[i];
    			 }
    			inputStream.close();
    			outputStream.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		return bufferSize;
    	}
    
    }
    
  • 相关阅读:
    约瑟夫环问题(Josephus)
    判断链表是否相交
    单链表相关操作实现
    C/C++一些库函数的实现
    指针数组和数组指针
    union关键字及大小端模式
    C/C++生成可执行文件过程
    当linux报 “-bash: fork: 无法分配内存”
    Starting MySQL.. ERROR! The server quit without updating PID file (/var/mysql/data/feng.pid). 问题解决方案
    ssh 和scp 非22端口
  • 原文地址:https://www.cnblogs.com/qinaidexin/p/4602632.html
Copyright © 2020-2023  润新知