I want to modify bytecode of java method of target process. I tried to inject this shared library into java process using this injector and it works, but res is always -1 (unknown error) and I have no idea why.
libinject.so
#include <jni.h>
#include <iostream>
struct Initializer {
Initializer() {
jsize count;
JavaVM *vm;
JNIEnv *env;
if (JNI_GetCreatedJavaVMs(&vm, 1, &count) != JNI_OK || count == 0) {
std::cout << "No JavaVMS found!" << std::endl;
return;
}
jint res = vm->GetEnv((void **) &env, JNI_VERSION_1_8);
if (res == JNI_EDETACHED) {
res = vm->AttachCurrentThread((void **) &env, nullptr);
}
// res == -1 :(
}
};
Initializer initializer;
I can't figure out where's the problem. Also I was using the same exact code but with DllMain on Windows and it worked..
Related
When I try and get a proc address for a function called print, it is able to load the ManualLinking.dll but not the function. The error code that windows gives is 127. The client app is almost a direct copy paste from windows.
DLL:
#include"pch.h"
#include<string>
#include<iostream>
__declspec(dllexport) void __stdcall print(std::string data) {
std::cout << data << std::endl;
}
CPP:
#include <windows.h>
#include<iostream>
#include"Header.h"
#include<string>
typedef void(__stdcall* MYPROC)(std::string data);
int main(void)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("ManualLinking.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "print");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd)("Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (!fRunTimeLinkSuccess) {
printf("Message printed from executable\n");
std::cout << GetLastError() << std::endl;
}
std::cin.get();
return 0;
}
You need to replace DLL code with:
#include"pch.h"
#include<string>
#include<iostream>
extern "C"{
__declspec(dllexport) void __stdcall print(std::string data) {
std::cout << data << std::endl;
}
}
If you still have same error, please, check if the executable can actually find the .dll
/*...*/
if (hinstLib != NULL)
{
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "print");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd)("Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
else
{
std::cout << "Cannot find dll" << std::endl;
}
/*...*/
I am using libssh's C++ wrapper (libsshpp.hpp) and I'm trying to call ssh_scp_new for an SCP routine by giving it my ssh::Session variable but I get the following error:
cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’ for argument ‘1’ to ‘ssh_scp_struct* ssh_scp_new(ssh_session, int, const char*)’
I am able to get SCP working by completely not using the C++ ssh::Session class and going with the C example but obviously this is not my preferred workaround. Looking at libsshpp.hpp I was able to find a getCSession() function but it is only privately accessible and I'm not sure how to use it (or if it's even what I think it is).
Here is my sample code:
#include <iostream>
#include <fstream>
#include <libssh/libsshpp.hpp>
int main()
{
int port = 22;
int verbosity = SSH_LOG_PROTOCOL;
ssh::Session session;
try
{
session.setOption(SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
session.setOption(SSH_OPTIONS_PORT, &port);
session.setOption(SSH_OPTIONS_USER, "user");
session.setOption(SSH_OPTIONS_HOST, "host");
session.connect();
if (session.isServerKnown() != SSH_SERVER_KNOWN_OK)
{
if (session.writeKnownhost() != SSH_OK)
{
std::cout << "writeKnownHost failed" << std::endl;
}
else
{
session.connect();
}
}
if (session.userauthPassword("password") !=
SSH_AUTH_SUCCESS)
{
std::cout << "Authentication Error" << std::endl;
}
ssh_scp scp;
int rc;
// error cannot convert ‘ssh::Session’ to ‘ssh_session {aka ssh_session_struct*}’
scp = ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
}
catch (ssh::SshException e)
{
std::cout << "Error during connection : ";
std::cout << e.getError() << std::endl;
}
return 0;
}
How do I SCP send or receive a file with libssh using C++ methods?
Thanks!
As you can see the error. You have to decide to weather use ssh::Session class or ssh_session structure. The libssh library is a C library, and it has just a C++ wrapper (that may not contain all functionalities like in the original language)
Here is how to send connect and send files using libssh library (current stable version 0.7.3) according to official documentation.
Using ssh_session: (in C)
-use ssh_new() to create a ssh_session pointer.
-use int ssh_connect(ssh_session session) to connect.
-use *int ssh_options_set ( ssh_session session, enum ssh_options_e type,const void * value )* Take a look on this documentation http://api.libssh.org/stable/group__libssh__session.html#ga7a801b85800baa3f4e16f5b47db0a73d
-add your controls
-send file using ssh_scp_new(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
-free the connection using ssh_free(ssh_session session)
//You can try this simple program (from official libssh tutorials)
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
int scp_write(ssh_session session)
{
ssh_scp scp;
int rc;
scp = ssh_scp_new
(session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
if (scp == NULL)
{
fprintf(stderr, "Error allocating scp session: %s\n", ssh_get_error(session));
return SSH_ERROR;
}
rc = ssh_scp_init(scp);
if (rc != SSH_OK)
{
fprintf(stderr, "Error initializing scp session: %s\n", ssh_get_error(session));
ssh_scp_free(scp);
return rc;
}
ssh_scp_close(scp);
ssh_scp_free(scp);
return SSH_OK;
}
int main(int argc, char* argv[])
ssh_session my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
return 1;
scp_write(my_ssh_session );
ssh_free(my_ssh_session);
return 0;
}
Using ssh::Session (in C++) well, no wrapper allows this currently :( .
Here is some useful examples for the use of libssh library. Hope it helps !
http://api.libssh.org/master/libssh_tutorial.html
I want to programmatically trace stacks from C for Node.js (JS addresses aside).
The following command gives me stacks with resolved c++ symbols.
sudo dtrace -C -n 'profile-101 /pid == 13221/ { ustack() }'
The following C code only returns addresses for Node's C/C++ code. What would be the equivalent?
#include <dtrace.h>
#include <signal.h>
#include <stdio.h>
struct ps_prochandle *g_pr;
static dtrace_hdl_t* g_dtp;
static int chewrec (const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg) {
// A NULL rec indicates that we've processed the last record.
if (rec == NULL) {
return (DTRACE_CONSUME_NEXT);
}
return (DTRACE_CONSUME_THIS);
}
static const char* g_prog =
"#pragma D option switchrate=1000hz\n"
"profile-1ms /pid == 13221/ {\n"
"ustack();\n"
"}";
static int g_intr;
static int g_exited;
static void intr (int signo) {
g_intr = 1;
}
int main (int argc, char** argv) {
int err;
if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
fprintf(stderr, "failed to initialize dtrace: %s\n", dtrace_errmsg(NULL, err));
return -1;
}
printf("Dtrace initialized\n");
(void) dtrace_setopt(g_dtp, "bufsize", "4m");
(void) dtrace_setopt(g_dtp, "aggsize", "4m");
printf("dtrace options set\n");
dtrace_prog_t* prog;
if ((prog = dtrace_program_strcompile(g_dtp, g_prog, DTRACE_PROBESPEC_NAME, DTRACE_C_CPP, 0, NULL)) == NULL) {
fprintf(stderr, "failed to compile dtrace program\n");
return -1;
} else {
printf("dtrace program compiled\n");
}
dtrace_proginfo_t info;
if (dtrace_program_exec(g_dtp, prog, &info) == -1) {
fprintf(stderr, "failed to enable dtrace probes\n");
return -1;
} else {
printf("dtrace probes enabled\n");
}
struct sigaction act;
(void) sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = intr;
(void) sigaction(SIGINT, &act, NULL);
(void) sigaction(SIGTERM, &act, NULL);
if (dtrace_go(g_dtp) != 0) {
fprintf(stderr, "could not start instrumentation\n");
return -1;
} else {
printf("instrumentation started ..\n");
}
int done = 0;
do {
if (!g_intr && !done) {
dtrace_sleep(g_dtp);
}
if (done || g_intr || g_exited) {
done = 1;
if (dtrace_stop(g_dtp) == -1) {
fprintf(stderr, "could not stop tracing\n");
return -1;
}
}
switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) {
case DTRACE_WORKSTATUS_DONE:
done = 1;
break;
case DTRACE_WORKSTATUS_OKAY:
break;
default:
fprintf(stderr, "processing aborted");
return -1;
}
} while (!done);
printf("closing dtrace\n");
dtrace_close(g_dtp);
return 0;
}
From the dtrace-Mailing list, Robert Mustacchi:
TL;DR resolve symbols yourself in userland.
"So, all the symbol resolution processing is always done in user land. In
other words, DTrace in the kernel only ever gathers addresses like
you're seeing for the cases where you're using ustack and not a ustack
handler via the jstack() action (jstack() also only returns symbols for
non-native frames). Note that if you want to see the JavaScript specific
symbols in addition to the native ones, you'll want to be using jstack()
in your examples and not ustack().
The way that these you can perform these mappings will change depending
on what system you're on. If you look at what DTrace does on illumos for
printing the results of ustack()
(http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libdtrace/common/dt_consume.c#1320),
then you'll see that it uses libproc and the Plookup_by_addr() function
to perform the translation. Though it's worth pointing out that neither
are stable interfaces, though they seldom change."
I am trying to create a microshell. It reads commands in, parses this and splits this, then executes. To parse, first I separate by the delimiter || to get up to two commands if there is a pipe. The split each command into an array of strings.
I thought this is how execlp works, but it only runs the command even though the C string "cmd1" does contain the arguments. Can someone please help me understand how I am passing the parameters wrong to the execlp function?
shell.h
/****************************************************************
PROGRAM: MicroShell(assignment 4)
FILE: shell.h
AUTHOR: Nick Schuck
FUNCTION: This contains the header for the shell class
****************************************************************/
#ifndef _shell_h
#define _shell_h
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
#include <pwd.h>
#include <cstring>
#include <sys/wait.h>
#include <cstdlib>
#include <vector>
class Shell
{
private:
char buffer[1024];
const char *cmd1[10];
const char *cmd2[10];
public:
Shell(); //default constructor
void askForCommand();
void readCommandLine();
void parseBuffer();
void invokeCommand();
void executeOneCommand();
void executeTwoCommands();
};
#endif
shell.cc
/***************************************************************
PROGRAM: MicroShell(assignment 4)
FILE: shell.c
AUTHOR: Nick Schuck
FUNCTION: This file contains the implementation of
class shell from file "shell.h"
****************************************************************/
#include "shell.h"
#include <iostream>
Shell::Shell()
{
/**Get current user*/
struct passwd *p = getpwuid(getuid());
if (!p) //Error handling
puts("Welcome to Nick Schuck's MicroShell, Anonymous");
/**Welcome message for my shell*/
printf("\n\nWelcome to Nick Schuck's Microshell, user %s!\n\n", p->pw_name);
}
void Shell::askForCommand()
{
/**Command Prompt*/
printf("myshell>");
}
void Shell::readCommandLine()
{
/**Read stdin into buffer array IF no*/
/**errors occur */
if (fgets(this->buffer, 1024, stdin) != NULL)
{
this->buffer[strlen(this->buffer) - 1] = 0;
}
}
void Shell::parseBuffer()
{
/**Variables*/
int i = 0, u = 0,
t = 0;
char *ptr;
char parsingBuffer[2][512];
/**Parse buffer for multiple commands*/
strcpy(parsingBuffer[0], strtok(this->buffer, "||"));
while ((ptr = strtok(NULL, "||")) != NULL)
{
i++;
strcpy(parsingBuffer[i], ptr);
}
//**Get first command*/
this->cmd1[0] = strtok(parsingBuffer[0], " ");
while ((ptr = strtok(NULL, " ")) != NULL)
{
u++;
this->cmd1[u] = ptr;
this->cmd1[u+1] = '\0';
}
//!!!TESTING TO SEE COMMAND ARE IN CMD1
int b = 0;
while(cmd1[b] != '\0')
{
std::cout << cmd1[b] << "\n";
b++;
}
/**Get second command*/
this->cmd2[0] = strtok(parsingBuffer[1], " ");
while ((ptr = strtok(NULL, " ")) != NULL)
{
t++;
this->cmd2[t] = ptr;
}
}
void Shell::invokeCommand()
{
if (this->cmd1[0] == NULL)
{
//do nothing
}
else if(this->cmd1[0] != NULL && this->cmd2[0] == NULL)
{
executeOneCommand();
}
else if(this->cmd1[0] != NULL && cmd2[0] !=NULL)
{
executeTwoCommands();
}
}
void Shell::executeOneCommand()
{
pid_t pid; //pid for fork
int status;
char args[512];
if ((pid = fork()) < 0)
{
printf("fork error\n");
exit(-1);
}
else if(pid == 0) //Child Process
{
execlp(cmd1[0], *cmd1);
}
else //Parent Process
{
if ((pid = waitpid(pid, &status, 0)) < 0)
{
printf("waitpid error in main\n");
exit(-1);
}
}
}
main.cc
#include "shell.h"
#include <iostream>
#include <vector>
int main()
{
const int BUFFER_SIZE = 1024;
const int MAX_COMMANDS_IN_BUFFER = 2;
/**Initialize a new shell object*/
Shell shell;
/**Print command prompt to screen*/
shell.askForCommand();
/**Read users command*/
shell.readCommandLine();
/**parse buffer to find individual*/
/**commands */
shell.parseBuffer();
/**Invoke command*/
shell.invokeCommand();
}
You can't use execlp() — you must use execvp().
execvp(cmd1[0], cmd1);
To use execlp(), you must know at compile time the fixed list of arguments for the command — you must be able to write:
execlp(cmd_name, arg0, arg1, …, argN, (char *)0);
Your call to execlp() is also faulty because you don't provide the (char *)0 argument to indicate the end of the argument list.
Your code also needs to handle exec*() returning, which means the command failed. Usually that means it should print an error message (that the command was not found, or permission denied, or whatever), and then exit with an appropriate non-zero error status.
I am building a client that:
Should be able to recieve information from both the server and the standart input
Should be able to recieve information from the server without asking, for example when another client sends a message.
To do so I tried using select to monitor both possible inputs.
What happens is that when a keyboard input is monitored I send a message to the client and I expect one back, so there's no problem. But when the server sends an unexpected message nothing happens, and I don't know why. Is using select() the proper way to do so? Is it even possible to use select() without listen()ing?
Here's my code (compileable):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <cstring>
#include <arpa/inet.h>
#include <iostream>
#include <fstream>
#define MAX_CLIENT_NAME 30
#define MAX_TWIT_SIZE 140
#define NUM_OF_ARG 4
#define ERROR -1
#define GREAT_SUCCESS 0
#define OK "OK"
#define EXIT "EXIT"
using std::string;
using std::cerr;
using std::endl;
using std::cout;
string clientName;
int srverfd, numbytes, status, maxSock ;
fd_set inputFdSet; /* Socket file descriptors we want to wake
up for, using select() */
int establishConnection(char * serverAddress,char * port){
if ((srverfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return ERROR;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
inet_aton(serverAddress, &server.sin_addr);
server.sin_port = htons(atoi(port));
memset(&(server.sin_zero), '\0', 8);
if (connect(srverfd,(const struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) {
perror("connect");
close(srverfd);
return ERROR;
}
maxSock = srverfd;
return GREAT_SUCCESS;
}
const char * getUserTweet(){
string temp;
getline(std::cin,temp);
return temp.c_str();
}
void sendMessage(string message){
if ((numbytes = send(srverfd, message.c_str(), message.length(), 0)) == -1) {
perror("sendMessage");
close(srverfd);
}
cout<<"Message sent: "<< message << endl;
return;
}
const char * getMessage(){
char buf[MAX_TWIT_SIZE];
memset(buf,'\0',MAX_TWIT_SIZE);
if ((numbytes = recv(srverfd, buf, 140, 0)) == -1) {
perror("getMessage");
close(srverfd);
}
string temp = buf;
return temp.c_str();
}
void build_select_list() {
FD_ZERO(&inputFdSet);
FD_SET(srverfd,&inputFdSet);
FD_SET(STDIN_FILENO,&inputFdSet);
if (STDIN_FILENO > maxSock)
maxSock = STDIN_FILENO;
return;
}
void readSocket(fd_set tempfd) {
const char * tweet, * inMessage;
if (FD_ISSET(srverfd,&tempfd)) {
inMessage = getMessage();
cout << inMessage << endl;
}
if (FD_ISSET(STDIN_FILENO,&tempfd)) {
tweet = getUserTweet();
sendMessage(tweet);
inMessage = getMessage();
if (strcmp(inMessage,OK) != 0) {
cout << inMessage << endl;
}
if (strcmp(inMessage,EXIT) == 0) {
return;
}
}
return;
}
int main (int argc, char *argv[] ){
int value;
bool clientON = false;
if(establishConnection(argv[2],argv[3])){
cerr << "usage: failed to make connection" << endl << "exiting..." << endl;
exit(EXIT_FAILURE);
}
cout << "Connected successfully" << endl;
sendMessage("CONNECT "+clientName); //Connect
if(strcmp(getMessage(),OK) == 0){
clientON = true;
}
while(clientON){
build_select_list();
value = select(maxSock, &inputFdSet, NULL, NULL, NULL);
if (value < 0) {
perror("select");
exit(EXIT_FAILURE);
}
if (value == 0) {
continue;
}
else {
readSocket(inputFdSet);
}
}
sendMessage("DISCONNECT");
if(strcmp(getMessage(),OK) == 0){
// do nothing
}
close(srverfd);
return 0;
}
Your select call is invalid. The first parameter must be the highest file descriptor in any of the sets, plus one.
As you have it, an event on srverfd will not "wake up" the select call (unless STDIN_FILENO was somehow less than srverfd, in which case stdin events wouldn't unlock select - but that won't happen in practice).
There are quite a few other problems with your code. (It doesn't really look like C++.)
getUserTweet is unreliable (undefined behavior - temp is destroyed as soon as the function returns, so the char* you return has disappeared by the time its caller will try to use it). Same for getMessage. To remedy that, use std::string everywhere, and only extract the char* when you call into C library functions).
readSocket needlessly copies the FD set (can be expensive).
You should really get rid of all those globals - build one or two classes to encapsulate that state and the networking functions, or something like that.