Sometimes it can be good to test how a program will behave if a TCP socket/connection that the program has created is closed.
For Windows it can easily be done by using Microsoft Windows Sysinternals program TCPView by right clicking on a TCP connection and choose "Close Connection". I'm not sure how it is implemented but by using Wireshark capture while closing a TCP connection you can see that a RST TCP segment is sent to the from your host to the remote side.
But with Linux it is a bit tricker. Here is a script I created that can do it:
#!/bin/bash
#Syntax: ./killtcp.sh 5328 10.10.14.41 14001
# PID IP PORT
pid=$1
ip=$2
port=$3
file_descriptors=`lsof -Pnp $pid`
echo "$file_descriptors" |grep TCP | grep $ip:$port | while read file_descriptor
do
handle=`echo $file_descriptor | cut -f4 -d' '`
handle=${handle/[a-z]/}
echo "call close($handle)" > gdb_debugger.txt
sudo gdb -p $pid -batch -x gdb_debugger.txt
done
It uses lsof to find out the internal file descriptor handle(s) of the application. Then it writes gdb close commands to a file (file was the only way I could get it into gdb). Then it uses gdb to connect to the PID of the program with the TCP connection and forces a close on the file handle(s).
This is not the cleanest way to do it. It might crash your application!? But I have used it successfully on ssh and some java programs I wrote and it worked okay.
11 December 2015
29 October 2015
How to make a JTable a specific number of rows high
Java Swing is rather complex. You can do just about anything, but it can be hard to know how to do it. I have for a long time tried to adapt the visible (preferred) size of a JTable. I know how many rows I would like to display, but it is hard to know how to write the code for it.
I figured out this code today:
package se.lesc.blog;
import java.awt.Insets;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
public class TableRowDemo extends JFrame {
Object[][] data = { {"Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe", "Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black", "Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White", "Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown", "Pool", new Integer(10), new Boolean(false)}
};
String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
public static void main(String [] args) {
new TableRowDemo().setVisible(true);
}
public TableRowDemo() {
GroupLayout layout = new GroupLayout(getContentPane());
JLabel label = new JLabel("My table:");
JTable table = new JTable(data, columnNames);
JScrollPane tableScrollPane = new JScrollPane(table);
int numberOfRowsToDisplay = 3;
//Fetch the border "padding"
Insets insets = tableScrollPane.getBorder().getBorderInsets(table);
//Compute the total height of the table
int preferredTableHeight = insets.bottom + insets.top
+ (int) table.getTableHeader().getPreferredSize().getHeight() +
numberOfRowsToDisplay * table.getRowHeight();
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(label)
.addComponent(tableScrollPane, DEFAULT_SIZE, preferredTableHeight, DEFAULT_SIZE)
);
layout.setHorizontalGroup(layout.createParallelGroup()
.addComponent(label)
.addComponent(tableScrollPane)
);
getContentPane().setLayout(layout);
pack();
}
}
I figured out this code today:
package se.lesc.blog;
import java.awt.Insets;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
public class TableRowDemo extends JFrame {
Object[][] data = { {"Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe", "Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black", "Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White", "Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown", "Pool", new Integer(10), new Boolean(false)}
};
String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
public static void main(String [] args) {
new TableRowDemo().setVisible(true);
}
public TableRowDemo() {
GroupLayout layout = new GroupLayout(getContentPane());
JLabel label = new JLabel("My table:");
JTable table = new JTable(data, columnNames);
JScrollPane tableScrollPane = new JScrollPane(table);
int numberOfRowsToDisplay = 3;
//Fetch the border "padding"
Insets insets = tableScrollPane.getBorder().getBorderInsets(table);
//Compute the total height of the table
int preferredTableHeight = insets.bottom + insets.top
+ (int) table.getTableHeader().getPreferredSize().getHeight() +
numberOfRowsToDisplay * table.getRowHeight();
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(label)
.addComponent(tableScrollPane, DEFAULT_SIZE, preferredTableHeight, DEFAULT_SIZE)
);
layout.setHorizontalGroup(layout.createParallelGroup()
.addComponent(label)
.addComponent(tableScrollPane)
);
getContentPane().setLayout(layout);
pack();
}
}
15 September 2015
How Microsoft SmartScreen works and how it stores data in NTFS streams
Windows 10
(and 8) has a feature called Microsoft SmartScreen. It is split in two parts:
one purely for the web and one for files downloaded for the web. I’ll try to
explain how SmartScreen for downloaded files work. But first we need to know how
streams works
ADS or just
”streams” is a feature in Microsoft NTFS file system feature that allows for ”hidden”
data in a file. You can access the hidden data by using the colon separator.
Copy
ftp.exe from C:\Windows\System32 to c:\temp\. I used ftp.exe because it is an
unsigned executable that you probably can find on your hard drive. Use Windows
PowerShell for these commands. Create an alternative stream by using notepad:
PS
C:\temp> notepad ftp.exe:LennartStream
Answer yes
in Notepad. Enter the content ”Hello World!”, save and close the file/stream.
We can now open the file/stream by the same Notepad command again. No actual new
file was created on the hard drive. It just created a new stream. You can
list the streams by using Windows Sysinternals Streams program or just use
PowerShell:
PS C:\temp> Get-Item ftp.exe -Stream *FileName: C:\temp\ftp.exe
Stream Length
------ ------
:$DATA 55808
LennartStream.txt 12
As you can
see my ”LennartStream” is there and it takes 12 bytes (the ”Hello World!”
string). The main program for ftp takes 55808 bytes.
Microsoft SmartScreen
SmartScreen
(https://en.wikipedia.org/wiki/Microsoft_SmartScreen) provides some protection for
executing downloaded files from the internet. When a file is downloaded in the web browser
(for example Firefox), a stream called “Zone.Identifier” is created. If the
Zone is “dangerous” a warning dialog may be presented to the user when the file
is run. In Windows 10 the settings for SmartScreen is in Control Panel\System
and Security\Security and Maintenance.
Use notepad
to edit the Zone.Identifier stream:
PS
C:\temp> notepad ftp.exe:Zone.Identifier
Create a
new stream and enter this content:
[ZoneTransfer]
ZoneId=3
Now double click
on ftp.exe to run it. You will now get a dialog like this:
“Windows
protected your PC. Windows SmartScreen prevented an unrecognized app from
starting. Running this app might put your PC at risk”
Press “More
info”:
Choose “Run
anyway” and then just close the ftp program. View the Zone.Identifier stream
again:
PS
C:\temp> notepad ftp.exe:Zone.Identifier
The content
has now changed to:
[ZoneTransfer]
AppZoneId=4
As you can
see SmartScreen has updated the stream data with respect to your answer in the
dialog.
Please note
that if the file is signed with a certificate and Microsoft can verify it (with
some magical “reputation” system I don’t know the details on) the dialog may
not be shown and the stream will not be changed.