Keylogger API and converting to a string - c#

I'm attempting to write a simple keylogger that will check typed words against a blacklist and fire a screenshot when a word is triggered. This is because we have a new PREVENT agenda that we have to use in UK schools to capture any possible extremist views.
I've been looking at the Keylogger API from https://github.com/fabriciorissetto/KeystrokeAPI
I'm using the following code as a test but i'm trying to add the characters to a string so i can then fire a comparison with a word list when the user presses the spacebar. The trouble i'm having is that i cannot convert character into a string. Is it possible do this so i can append it to another string a whilst waiting for a spacebar key?
class Program
{
static void Main(string[] args)
{
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => { Console.Write(character); });
Application.Run();
}
}
}
This is what i have so far, the error i get is on the if statement converting character to a string.
static void Main(string[] args)
{
string line = "";
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => {
line += character.ToString();
if (character.ToString() = "space")
{
Console.Write("Spacebar Hit");
}
Console.Write(character.KeyCode);
});
Application.Run();
}
}

Edit.
I rewrote this.
Captures both spaces and enter commands
static void Main(string[] args)
{
string line = string.Empty;
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => {
if (character.KeyCode.ToString() == "Space" || character.KeyCode.ToString() == "Return")
{
if(BannedWordsCheck(line))
{
Console.WriteLine("Banned Word Typed: " + line);
}
line = string.Empty;
}
else
{
line += character.KeyCode.ToString();
}
});
Application.Run();
}
}
static bool BannedWordsCheck(string word)
{
if(word.ToLower().Contains("terror"))
{
return true;
}
else
{
return false;
}
}

The error you are receiving in your code is due to the following line
if (character.ToString() = "space")
You are attempting to assign the string literal "space" to character.ToString(), I also have this error in my comment which I can't edit anymore.
Here's a snippet that will check the key code against an enum instead of a string, it will then call the HandleComparison method if Space was pressed, and then clear out the StringBuilder
The only issue I found here is that pressing Shift will prefix the string with <shift>, so some additional logic will have to be applied for action keys, but this is a base to get you started with a working code sample.
I hope this helps.
class Program
{
private static StringBuilder builder;
static void Main(string[] args)
{
using (var api = new KeystrokeAPI())
{
builder = new StringBuilder();
api.CreateKeyboardHook(HandleKeyPress);
Application.Run();
}
}
private static void HandleKeyPress(KeyPressed obj)
{
// To be more reliable, lets use the KeyCode enum instead
if (obj.KeyCode == KeyCode.Space)
{
// Spacebar was pressed, let's check the word and flush the StringBuilder
HandleComparison(builder.ToString());
builder.Clear();
return;
}
// Space wasn't pressed, let's add the word to the StringBuilder
builder.Append(obj);
}
// Handle comparison logic here, I.E check word if exists on blacklist
private static void HandleComparison(string compareString)
{
Console.WriteLine(compareString);
}
}

Could you use the StringBuilder as a buffer?
something like this
var buffer = new StringBuilder();
using (var api = new KeystrokeAPI())
{
api.CreateKeyboardHook((character) => {
if (character.ToString() == " ")
{
//check the word
CallSomeMethodToCheckWord(buffer.ToString());
//reset the buffer
buffer = new StringBuilder();
}
else
{
//ToString returns special characters in it, so you could append here and parse later, or parse here.
buffer.Append(character.ToString());
}
});
Application.Run();
}

Related

Roslyn scripting entry point?

I am building a REPL interface with Blazor webassembly.
I have build a textarea where you can write code. The code compiles successfully. The problem is that the textarea is empty. Normally, as a C# developer, you would see an entry point (the Main method) by which the program starts.
How do I fix that?
Try dotnet is an good example of what I want to achieve. In my case the textarea is empty, but I can program in there. Not sure what the entry point is in my case.
I am really stuck here since I cannot find much about Roslyn scripting with Blazor.
Please help me out.
My code to compile input:
private ScriptState _scriptState = null;
private StringWriter _sw;
private string _output;
public ChallengeCompiler()
{
_sw = new StringWriter();
Console.SetOut(_sw);
Console.SetError(_sw);
}
public string CompileCode(string input)
{
string[] references =
{
"System",
"System.Collections",
"System.Collections.Generic",
"System.Collections.Concurrent",
"System.Console",
"System.Diagnostics.Debug",
"System.Diagnostics.Process",
"System.Diagnostics.StackTrace",
"System.Globalization",
"System.IO",
"System.Reflection",
"System.Runtime",
"System.Runtime.InteropServices",
"System.Text",
"System.Text.Encoding",
"System.Text.RegularExpressions",
"System.Threading",
"System.Threading.Tasks",
"System.Threading.Tasks.Parallel",
"System.Threading.Thread",
"System.ValueTuple",
};
try
{
if (_scriptState == null)
{
_scriptState = CSharpScript.RunAsync(input, ScriptOptions.Default.WithImports(references)).Result;
}
else
{
_scriptState = _scriptState.ContinueWithAsync(input).Result;
}
if (_scriptState.ReturnValue != null && !string.IsNullOrEmpty(_scriptState.ReturnValue.ToString()))
{
_output = _scriptState.ReturnValue.ToString();
}
else
{
_output = _sw.ToString();
}
}
catch (CompilationErrorException e)
{
_output = "-----------------------------------\n";
_output += string.Join(Environment.NewLine, e.Diagnostics);
}
return _output;
}

Set up twitter stream to get live streams from a user based on keywords

If I want a stream when Trump tweets anything with the word "racist" or "immigration", how do I do that? I am not sure even this works, let alone how to add multiple keywords to the query.
public static void Stream_SampleStreamExample()
{
var stream = Stream.CreateUserStream();
stream.AddCustomQueryParameter("realDonaldTrump", "racist");
stream.MessageReceived += (sender, args) =>
{
Console.WriteLine(args.Message.Text);
};
stream.AddTweetLanguageFilter(LanguageFilter.English);
stream.StartStream();
}
Do I have to follow a user first?
public static void AuthenticatedUser_FollowUser(string userName)
{
var authenticatedUser = User.GetAuthenticatedUser();
var userToFollow = User.GetUserFromScreenName(userName);
if (authenticatedUser.FollowUser(userToFollow))
{
Console.WriteLine("You have successfully sent a request to follow {0}", userToFollow.Name);
}
}
For now this works. First
string userStr = "realDonaldTrump";
// From a user screen name
user = User.GetUserFromScreenName(userStr);
userIdentifier = new UserIdentifier(user.Id);
Add the keywords to match on:
fs.AddTrack("immigration");
...
Setup a filtered stream:
IFilteredStream fs = Stream.CreateFilteredStream();
and so on...
Then, inside OnMatchedTweet, see if the creator of the tweet is the user you want.
OnMatchedTweet(object sender, MatchedTweetReceivedEventArgs args)
{
if (args.Tweet.CreatedBy.Id != user.Id)
return;
...
}

How to get pronunciation phonemes corresponding to a word using C#?

I'll preface this by saying I'm very novice when it comes to C# programming. I'm working on an application for programmatically modifying the Windows Speech Dictionary using C# in conjunction with SAPI v5.4 (speechlib). Everything is working well so far but I need to gain more insight about how strings are interpreted when they are synthesized (voiced).
My understanding is that in SAPI 5.4 words are broken down into phoneme representations, and I had some success getting word pronunciations to be "trained" correctly using the phonemes. I also know I can add words manually to the Windows Speech Recognition dictionary, provide a voice recording, and then extract the word's pronunciation (phonemes)...but this is cumbersome. It would also be useful to explore how the words are synthesized by default, i.e. without input from me (like how does the synthesizer interpret "dolphins"?).
From a coding point of view here's what I've got so far:
using System;
using System.Speech.Synthesis;
namespace SpeechTest
{
class Program
{
static void Main(string[] args)
{
// Set up the speech synthesizer
SpeechSynthesizer synthesizer = new SpeechSynthesizer();
synthesizer.Volume = 100;
synthesizer.Rate = -2;
// Configure the audio output
synthesizer.SetOutputToDefaultAudioDevice();
// Initialize string to store word of interest (not in the speech dictionary)
string myWord = "dolphins";
// Speak the word of interest
synthesizer.Speak(myWord);
// Retrieve pronunciation of myWord
string myPronunciation = // *some code here*
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
}
Thanks to the amazing work of Casey Chesnut I've figured out how to determine the IPA phones for a given string. Now I just have to figure out how to convert from IPA phones to SAPI symbols, but that's for a separate topic (see here for how to get the SAPI phonemes from a text string).
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Windows.Forms;
namespace SpeechTest
{
class Program
{
static void Main(string[] args)
{
string MyText = "dolphins"; // Initialze string for storing word (or words) of interest
string MyPronunciation = GetPronunciationFromText(MyText.Trim()); // Get IPA pronunciations of MyTe
MessageBox.Show(MyText + " = " + MyPronunciation); // Output MyText and MyPronunciation
}
public static string recoPhonemes;
public static string GetPronunciationFromText(string MyWord)
{
//this is a trick to figure out phonemes used by synthesis engine
//txt to wav
using (MemoryStream audioStream = new MemoryStream())
{
using (SpeechSynthesizer synth = new SpeechSynthesizer())
{
synth.SetOutputToWaveStream(audioStream);
PromptBuilder pb = new PromptBuilder();
//pb.AppendBreak(PromptBreak.ExtraSmall); //'e' wont be recognized if this is large, or non-existent?
//synth.Speak(pb);
synth.Speak(MyWord);
//synth.Speak(pb);
synth.SetOutputToNull();
audioStream.Position = 0;
//now wav to txt (for reco phonemes)
recoPhonemes = String.Empty;
GrammarBuilder gb = new GrammarBuilder(MyWord);
Grammar g = new Grammar(gb); //TODO the hard letters to recognize are 'g' and 'e'
SpeechRecognitionEngine reco = new SpeechRecognitionEngine();
reco.SpeechHypothesized += new EventHandler<SpeechHypothesizedEventArgs>(reco_SpeechHypothesized);
reco.SpeechRecognitionRejected += new EventHandler<SpeechRecognitionRejectedEventArgs>(reco_SpeechRecognitionRejected);
reco.UnloadAllGrammars(); //only use the one word grammar
reco.LoadGrammar(g);
reco.SetInputToWaveStream(audioStream);
RecognitionResult rr = reco.Recognize();
reco.SetInputToNull();
if (rr != null)
{
recoPhonemes = StringFromWordArray(rr.Words, WordType.Pronunciation);
}
//txtRecoPho.Text = recoPhonemes;
return recoPhonemes;
}
}
}
public static string StringFromWordArray(ReadOnlyCollection<RecognizedWordUnit> words, WordType type)
{
string text = "";
foreach (RecognizedWordUnit word in words)
{
string wordText = "";
if (type == WordType.Text || type == WordType.Normalized)
{
wordText = word.Text;
}
else if (type == WordType.Lexical)
{
wordText = word.LexicalForm;
}
else if (type == WordType.Pronunciation)
{
wordText = word.Pronunciation;
//MessageBox.Show(word.LexicalForm);
}
else
{
throw new InvalidEnumArgumentException(String.Format("[0}: is not a valid input", type));
}
//Use display attribute
if ((word.DisplayAttributes & DisplayAttributes.OneTrailingSpace) != 0)
{
wordText += " ";
}
if ((word.DisplayAttributes & DisplayAttributes.TwoTrailingSpaces) != 0)
{
wordText += " ";
}
if ((word.DisplayAttributes & DisplayAttributes.ConsumeLeadingSpaces) != 0)
{
wordText = wordText.TrimStart();
}
if ((word.DisplayAttributes & DisplayAttributes.ZeroTrailingSpaces) != 0)
{
wordText = wordText.TrimEnd();
}
text += wordText;
}
return text;
}
public static void reco_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
{
recoPhonemes = StringFromWordArray(e.Result.Words, WordType.Pronunciation);
}
public static void reco_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
{
recoPhonemes = StringFromWordArray(e.Result.Words, WordType.Pronunciation);
}
}
public enum WordType
{
Text,
Normalized = Text,
Lexical,
Pronunciation
}
}
// Credit for method of retrieving IPA pronunciation from a string goes to Casey Chesnut (http://www.mperfect.net/speechSamples/)

some delay processing message in MessageInterceptor

Sorry, my english is not quite well.
I'm new in programming world and tried to create an application using messageinterceptor on windows mobile 6.5.3.
but when i send text message to my phone, there was delay about 30 seconds or more before the message is processed, either text message which contain keywords or not.
I read several sources before deciding to try to make my own application, but these source are using Windows Form (GUI), instead of using Windows Form, i make it run in console mode.
here is the code:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.WindowsMobile.PocketOutlook.MessageInterception;
using Microsoft.WindowsMobile.PocketOutlook;
using Microsoft.WindowsMobile;
using System.IO;
namespace PenerimaPesan
{
class Program
{
static void Main(string[] args)
{
string applicationID;
applicationID = "tracker";
MessageInterceptor pesanmasuk = null;
pesanmasuk = new MessageInterceptor();
pesanmasuk.EnableApplicationLauncher(applicationID);
if (MessageInterceptor.IsApplicationLauncherEnabled(applicationID))
{
string keyword;
StreamReader key = new StreamReader(#"\Windows\conf.txt");
string data = key.ReadToEnd();
string[] isi = data.Split(new char[] { '\n' });
keyword = isi[1];
keyword = keyword.Replace(" ", "");
pesanmasuk = new MessageInterceptor(InterceptionAction.NotifyAndDelete, false);
pesanmasuk.MessageCondition = new MessageCondition(MessageProperty.Body, MessagePropertyComparisonType.StartsWith, ""+keyword);
pesanmasuk.MessageReceived += new MessageInterceptorEventHandler(pesanmasuk_MessageReceived);
}
}
static void pesanmasuk_MessageReceived(object sender, MessageInterceptorEventArgs e)
{
SmsMessage pesan = e.Message as SmsMessage;
if (pesan != null)
{
string perintah;
string[] command = pesan.Body.Split(new char[] { '.' });
perintah = command[1];
if (perintah == "helo")
/*do some Stuff*/
}
}
}
I've never used MessageInterceptor, so I decided I'd try to implement this code in my application. To test it, I renamed Main to Main2, then cleaned it up to match "my style".
Anyway, I ran into errors when I tried wrapping the MessageInterceptor in a using block - not because MessageInterceptor does not implement IDispose, but because you have declared a new instance of it.
Take a look at this snippet of your code:
MessageInterceptor pesanmasuk = new MessageInterceptor();
pesanmasuk.EnableApplicationLauncher(applicationID);
if (MessageInterceptor.IsApplicationLauncherEnabled(applicationID)) {
string keyword;
StreamReader key = new StreamReader(#"\Windows\conf.txt");
string data = key.ReadToEnd();
string[] isi = data.Split(new char[] { '\n' });
keyword = isi[1];
keyword = keyword.Replace(" ", "");
pesanmasuk = new MessageInterceptor(InterceptionAction.NotifyAndDelete, false);
OK, right there. Stop. You created a new instance of your pesanmasuk variable, set Properties, did some checking, worked with data from a text file, then...
Created a new instance of your pesanmasuk variable.
All of your previous settings are now whipped out.
I'm guessing your first instance is running and perhaps the second instance has to wait for the first instance to time out before it can be created.
At this point, I'm interested to learn just how to use this MessageInterceptor on MSDN, looked into the example there, and came up with this [untested] version:
static void Main2(string[] args) {
const string stackOverflowUrl = #"http://stackoverflow.com/questions/8520488/some-delay-processing-message-in-messageinterceptor";
string empty = String.Empty;
StreamReader key = new StreamReader(#"\Windows\conf.txt");
string data = key.ReadToEnd();
string[] lines = data.Split(new char[] { '\n' });
string keyword = lines[1].Replace(" ", empty);
string applicationID = "trackingApplication";
using (MessageInterceptor smsInterceptor = new MessageInterceptor(applicationID, false)) {
smsInterceptor.InterceptionAction = InterceptionAction.NotifyAndDelete;
smsInterceptor.MessageCondition = new MessageCondition(MessageProperty.Body, MessagePropertyComparisonType.StartsWith, empty + keyword);
smsInterceptor.MessageReceived += new MessageInterceptorEventHandler(Intercept_MessageReceived);
smsInterceptor.EnableApplicationLauncher(applicationID);
if (MessageInterceptor.IsApplicationLauncherEnabled(applicationID)) {
// Here, you'd need to launch your Form1 or enable some timer,
// otherwise the code will return immediately and the MessageInterceptor
// instance will be disposed of.
}
smsInterceptor.MessageReceived -= MessageInterceptorEventHandler;
}
}
static void Intercept_MessageReceived(object sender, MessageInterceptorEventArgs e) {
SmsMessage newMessage = e.Message as SmsMessage;
if (newMessage != null) {
Console.WriteLine("From: {0}", newMessage.From.Address);
Console.WriteLine("Body: {0}", newMessage.Body);
string[] command = newMessage.Body.Split(new char[] { '.' });
string line = command[1];
if (line == "helo") {
/*do some Stuff*/
}
}
}
I hope this helps, but keep in mind that I've never actually used this control and my code has not been tested.

Why won't MSMQ send a space character?

I'm exploring MSMQ services, and I wrote a simple console client-server application that sends each of the client's keystrokes to the server. Whenever hit a control character (DEL, ESC, INS, etc) the server understandably throws an error. However, whenever I type a space character, the server receives the packet but doesn't throw an error and doesn't display the space.
Server:
namespace QIM
{
class Program
{
const string QUEUE = #".\Private$\qim";
static MessageQueue _mq;
static readonly object _mqLock = new object();
static XmlSerializer xs;
static void Main(string[] args)
{
lock (_mqLock)
{
if (!MessageQueue.Exists(QUEUE))
_mq = MessageQueue.Create(QUEUE);
else
_mq = new MessageQueue(QUEUE);
}
xs = new XmlSerializer(typeof(string));
_mq.BeginReceive(new TimeSpan(0, 1, 0), new object(), OnReceive);
while (Console.ReadKey().Key != ConsoleKey.Escape) { }
}
static void OnReceive(IAsyncResult result)
{
Message msg;
lock (_mqLock)
{
try
{
msg = _mq.EndReceive(result);
Console.Write(".");
Console.Write(xs.Deserialize(msg.BodyStream));
}
catch (Exception ex)
{
Console.Write(ex);
}
}
_mq.BeginReceive(new TimeSpan(0, 1, 0), new object(), OnReceive);
}
}
}
Client:
namespace QIM_Client
{
class Program
{
const string QUEUE = #".\Private$\qim";
static MessageQueue _mq;
static void Main(string[] args)
{
if (!MessageQueue.Exists(QUEUE))
_mq = MessageQueue.Create(QUEUE);
else
_mq = new MessageQueue(QUEUE);
ConsoleKeyInfo key = new ConsoleKeyInfo();
while (key.Key != ConsoleKey.Escape)
{
key = Console.ReadKey();
_mq.Send(key.KeyChar.ToString());
}
}
}
}
Client Input:
Testing, Testing...
Server Output:
.T.e.s.t.i.n.g.,..T.e.s.t.i.n.g......
You'll notice that the space character sends a message, but the character isn't displayed.
Your issue is not with MSMQ, it's with the XmlSerializer class. See:
var key = Console.ReadKey();
XmlSerializer s = new XmlSerializer(typeof(string));
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
s.Serialize(ms, key.KeyChar.ToString());
ms.Position = 0;
var foo = (string)s.Deserialize(ms);
}
If you type a space in the console, you'll see that key.KeyChar.ToString() yields " ", but foo is equal to "". Because of the default implementation of XmlReader, the XmlSerializer class considers a string of only whitespace to be empty; if the string contains any other characters, both leading and trailing spaces are preserved. The whitespace does get serialized, but deserializing it turns it into an empty string.
Use this instead:
Console.Write(
s.Deserialize(System.Xml.XmlReader.Create(msg.BodyStream,
new System.Xml.XmlReaderSettings()
{
IgnoreWhitespace = false
})));
The answer from #Adam is right. The easiest solution is to use BinaryMessageFormatter (it will result in slightly smaller messages anyway).
After you initialize the message queue objects in both the client and the server, set the formatter explicitly:
_mq.Formatter = new BinaryMessageFormatter();
Then in the server, don't try to mess with BodyStream directly. Instead just use Body (which will have already been deserialized by the formatter):
Console.Write(".");
Console.Write(msg.Body);

Categories